| 
									
										
										
										
											2024-02-01 18:11:57 +08:00
										 |  |  | import json | 
					
						
							|  |  |  | import logging | 
					
						
							|  |  |  | import mimetypes | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | from collections.abc import Generator | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | from os import listdir, path | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | from threading import Lock | 
					
						
							|  |  |  | from typing import TYPE_CHECKING, Any, Union, cast | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from yarl import URL | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import contexts | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  | from core.plugin.entities.plugin import ToolProviderID | 
					
						
							| 
									
										
										
										
											2025-04-27 14:22:25 +08:00
										 |  |  | from core.plugin.impl.tool import PluginToolManager | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | from core.tools.__base.tool_provider import ToolProviderController | 
					
						
							|  |  |  | from core.tools.__base.tool_runtime import ToolRuntime | 
					
						
							|  |  |  | from core.tools.plugin_tool.provider import PluginToolProviderController | 
					
						
							|  |  |  | from core.tools.plugin_tool.tool import PluginTool | 
					
						
							|  |  |  | from core.tools.workflow_as_tool.provider import WorkflowToolProviderController | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if TYPE_CHECKING: | 
					
						
							|  |  |  |     from core.workflow.nodes.tool.entities import ToolEntity | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-17 22:26:18 +08:00
										 |  |  | from configs import dify_config | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | from core.agent.entities import AgentToolEntity | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  | from core.app.entities.app_invoke_entities import InvokeFrom | 
					
						
							| 
									
										
										
										
											2024-06-05 00:13:04 +08:00
										 |  |  | from core.helper.module_import_helper import load_single_subclass_from_source | 
					
						
							| 
									
										
										
										
											2024-08-20 23:16:43 -04:00
										 |  |  | from core.helper.position_helper import is_filtered | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | from core.model_runtime.utils.encoders import jsonable_encoder | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | from core.tools.__base.tool import Tool | 
					
						
							|  |  |  | from core.tools.builtin_tool.provider import BuiltinToolProviderController | 
					
						
							|  |  |  | from core.tools.builtin_tool.providers._positions import BuiltinToolProviderSort | 
					
						
							|  |  |  | from core.tools.builtin_tool.tool import BuiltinTool | 
					
						
							|  |  |  | from core.tools.custom_tool.provider import ApiToolProviderController | 
					
						
							|  |  |  | from core.tools.custom_tool.tool import ApiTool | 
					
						
							|  |  |  | from core.tools.entities.api_entities import ToolProviderApiEntity, ToolProviderTypeApiLiteral | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | from core.tools.entities.common_entities import I18nObject | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | from core.tools.entities.tool_entities import ( | 
					
						
							|  |  |  |     ApiProviderAuthType, | 
					
						
							|  |  |  |     ToolInvokeFrom, | 
					
						
							|  |  |  |     ToolParameter, | 
					
						
							|  |  |  |     ToolProviderType, | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  | from core.tools.errors import ToolNotFoundError, ToolProviderNotFoundError | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  | from core.tools.tool_label_manager import ToolLabelManager | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | from core.tools.utils.configuration import ( | 
					
						
							|  |  |  |     ProviderConfigEncrypter, | 
					
						
							|  |  |  |     ToolParameterConfigurationManager, | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | from core.tools.workflow_as_tool.tool import WorkflowTool | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | from extensions.ext_database import db | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  | from models.tools import ApiToolProvider, BuiltinToolProvider, WorkflowToolProvider | 
					
						
							|  |  |  | from services.tools.tools_transform_service import ToolTransformService | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | logger = logging.getLogger(__name__) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 23:16:43 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | class ToolManager: | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |     _builtin_provider_lock = Lock() | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     _hardcoded_providers: dict[str, BuiltinToolProviderController] = {} | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |     _builtin_providers_loaded = False | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |     _builtin_tools_labels: dict[str, Union[I18nObject, None]] = {} | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     def get_hardcoded_provider(cls, provider: str) -> BuiltinToolProviderController: | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         get the hardcoded provider | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         if len(cls._hardcoded_providers) == 0: | 
					
						
							|  |  |  |             # init the builtin providers | 
					
						
							|  |  |  |             cls.load_hardcoded_providers_cache() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return cls._hardcoded_providers[provider] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def get_builtin_provider( | 
					
						
							|  |  |  |         cls, provider: str, tenant_id: str | 
					
						
							|  |  |  |     ) -> BuiltinToolProviderController | PluginToolProviderController: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         get the builtin provider | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :param provider: the name of the provider | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         :param tenant_id: the id of the tenant | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :return: the provider | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         # split provider to | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if len(cls._hardcoded_providers) == 0: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |             # init the builtin providers | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             cls.load_hardcoded_providers_cache() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if provider not in cls._hardcoded_providers: | 
					
						
							|  |  |  |             # get plugin provider | 
					
						
							|  |  |  |             plugin_provider = cls.get_plugin_provider(provider, tenant_id) | 
					
						
							|  |  |  |             if plugin_provider: | 
					
						
							|  |  |  |                 return plugin_provider | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return cls._hardcoded_providers[provider] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def get_plugin_provider(cls, provider: str, tenant_id: str) -> PluginToolProviderController: | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         get the plugin provider | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         # check if context is set | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             contexts.plugin_tool_providers.get() | 
					
						
							|  |  |  |         except LookupError: | 
					
						
							|  |  |  |             contexts.plugin_tool_providers.set({}) | 
					
						
							|  |  |  |             contexts.plugin_tool_providers_lock.set(Lock()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with contexts.plugin_tool_providers_lock.get(): | 
					
						
							|  |  |  |             plugin_tool_providers = contexts.plugin_tool_providers.get() | 
					
						
							|  |  |  |             if provider in plugin_tool_providers: | 
					
						
							|  |  |  |                 return plugin_tool_providers[provider] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             manager = PluginToolManager() | 
					
						
							|  |  |  |             provider_entity = manager.fetch_tool_provider(tenant_id, provider) | 
					
						
							|  |  |  |             if not provider_entity: | 
					
						
							|  |  |  |                 raise ToolProviderNotFoundError(f"plugin provider {provider} not found") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             controller = PluginToolProviderController( | 
					
						
							|  |  |  |                 entity=provider_entity.declaration, | 
					
						
							|  |  |  |                 plugin_id=provider_entity.plugin_id, | 
					
						
							|  |  |  |                 plugin_unique_identifier=provider_entity.plugin_unique_identifier, | 
					
						
							|  |  |  |                 tenant_id=tenant_id, | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             plugin_tool_providers[provider] = controller | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         return controller | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     def get_builtin_tool(cls, provider: str, tool_name: str, tenant_id: str) -> BuiltinTool | PluginTool | None: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         get the builtin tool | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :param provider: the name of the provider | 
					
						
							|  |  |  |         :param tool_name: the name of the tool | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         :param tenant_id: the id of the tenant | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :return: the provider, the tool | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         provider_controller = cls.get_builtin_provider(provider, tenant_id) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         tool = provider_controller.get_tool(tool_name) | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |         if tool is None: | 
					
						
							|  |  |  |             raise ToolNotFoundError(f"tool {tool_name} not found") | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return tool | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |     def get_tool_runtime( | 
					
						
							|  |  |  |         cls, | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         provider_type: ToolProviderType, | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         provider_id: str, | 
					
						
							|  |  |  |         tool_name: str, | 
					
						
							|  |  |  |         tenant_id: str, | 
					
						
							|  |  |  |         invoke_from: InvokeFrom = InvokeFrom.DEBUGGER, | 
					
						
							|  |  |  |         tool_invoke_from: ToolInvokeFrom = ToolInvokeFrom.AGENT, | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     ) -> Union[BuiltinTool, PluginTool, ApiTool, WorkflowTool]: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         get the tool runtime | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :param provider_type: the type of the provider | 
					
						
							| 
									
										
										
										
											2025-03-31 13:19:15 +08:00
										 |  |  |         :param provider_id: the id of the provider | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :param tool_name: the name of the tool | 
					
						
							| 
									
										
										
										
											2025-03-31 13:19:15 +08:00
										 |  |  |         :param tenant_id: the tenant id | 
					
						
							|  |  |  |         :param invoke_from: invoke from | 
					
						
							|  |  |  |         :param tool_invoke_from: the tool invoke from | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :return: the tool | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         if provider_type == ToolProviderType.BUILT_IN: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |             # check if the builtin tool need credentials | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             provider_controller = cls.get_builtin_provider(provider_id, tenant_id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             builtin_tool = provider_controller.get_tool(tool_name) | 
					
						
							|  |  |  |             if not builtin_tool: | 
					
						
							|  |  |  |                 raise ToolProviderNotFoundError(f"builtin tool {tool_name} not found") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |             if not provider_controller.need_credentials: | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                 return cast( | 
					
						
							|  |  |  |                     BuiltinTool, | 
					
						
							|  |  |  |                     builtin_tool.fork_tool_runtime( | 
					
						
							|  |  |  |                         runtime=ToolRuntime( | 
					
						
							|  |  |  |                             tenant_id=tenant_id, | 
					
						
							|  |  |  |                             credentials={}, | 
					
						
							|  |  |  |                             invoke_from=invoke_from, | 
					
						
							|  |  |  |                             tool_invoke_from=tool_invoke_from, | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  |                     ), | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             if isinstance(provider_controller, PluginToolProviderController): | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |                 provider_id_entity = ToolProviderID(provider_id) | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                 # get credentials | 
					
						
							|  |  |  |                 builtin_provider: BuiltinToolProvider | None = ( | 
					
						
							|  |  |  |                     db.session.query(BuiltinToolProvider) | 
					
						
							|  |  |  |                     .filter( | 
					
						
							|  |  |  |                         BuiltinToolProvider.tenant_id == tenant_id, | 
					
						
							| 
									
										
										
										
											2025-02-28 15:05:16 +08:00
										 |  |  |                         (BuiltinToolProvider.provider == str(provider_id_entity)) | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                         | (BuiltinToolProvider.provider == provider_id_entity.provider_name), | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                     .first() | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                 if builtin_provider is None: | 
					
						
							|  |  |  |                     raise ToolProviderNotFoundError(f"builtin provider {provider_id} not found") | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 builtin_provider = ( | 
					
						
							|  |  |  |                     db.session.query(BuiltinToolProvider) | 
					
						
							|  |  |  |                     .filter(BuiltinToolProvider.tenant_id == tenant_id, (BuiltinToolProvider.provider == provider_id)) | 
					
						
							|  |  |  |                     .first() | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if builtin_provider is None: | 
					
						
							|  |  |  |                     raise ToolProviderNotFoundError(f"builtin provider {provider_id} not found") | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |             # decrypt the credentials | 
					
						
							|  |  |  |             credentials = builtin_provider.credentials | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             tool_configuration = ProviderConfigEncrypter( | 
					
						
							|  |  |  |                 tenant_id=tenant_id, | 
					
						
							|  |  |  |                 config=[x.to_basic_provider_config() for x in provider_controller.get_credentials_schema()], | 
					
						
							|  |  |  |                 provider_type=provider_controller.provider_type.value, | 
					
						
							|  |  |  |                 provider_identity=provider_controller.entity.identity.name, | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-07-06 09:54:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             decrypted_credentials = tool_configuration.decrypt(credentials) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return cast( | 
					
						
							|  |  |  |                 BuiltinTool, | 
					
						
							|  |  |  |                 builtin_tool.fork_tool_runtime( | 
					
						
							|  |  |  |                     runtime=ToolRuntime( | 
					
						
							|  |  |  |                         tenant_id=tenant_id, | 
					
						
							|  |  |  |                         credentials=decrypted_credentials, | 
					
						
							|  |  |  |                         runtime_parameters={}, | 
					
						
							|  |  |  |                         invoke_from=invoke_from, | 
					
						
							|  |  |  |                         tool_invoke_from=tool_invoke_from, | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                 ), | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         elif provider_type == ToolProviderType.API: | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |             api_provider, credentials = cls.get_api_provider_controller(tenant_id, provider_id) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # decrypt the credentials | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             tool_configuration = ProviderConfigEncrypter( | 
					
						
							|  |  |  |                 tenant_id=tenant_id, | 
					
						
							|  |  |  |                 config=[x.to_basic_provider_config() for x in api_provider.get_credentials_schema()], | 
					
						
							|  |  |  |                 provider_type=api_provider.provider_type.value, | 
					
						
							|  |  |  |                 provider_identity=api_provider.entity.identity.name, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             decrypted_credentials = tool_configuration.decrypt(credentials) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return cast( | 
					
						
							|  |  |  |                 ApiTool, | 
					
						
							|  |  |  |                 api_provider.get_tool(tool_name).fork_tool_runtime( | 
					
						
							|  |  |  |                     runtime=ToolRuntime( | 
					
						
							|  |  |  |                         tenant_id=tenant_id, | 
					
						
							|  |  |  |                         credentials=decrypted_credentials, | 
					
						
							|  |  |  |                         invoke_from=invoke_from, | 
					
						
							|  |  |  |                         tool_invoke_from=tool_invoke_from, | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                 ), | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         elif provider_type == ToolProviderType.WORKFLOW: | 
					
						
							|  |  |  |             workflow_provider = ( | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |                 db.session.query(WorkflowToolProvider) | 
					
						
							|  |  |  |                 .filter(WorkflowToolProvider.tenant_id == tenant_id, WorkflowToolProvider.id == provider_id) | 
					
						
							|  |  |  |                 .first() | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if workflow_provider is None: | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |                 raise ToolProviderNotFoundError(f"workflow provider {provider_id} not found") | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             controller = ToolTransformService.workflow_provider_to_controller(db_provider=workflow_provider) | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             controller_tools: list[WorkflowTool] = controller.get_tools(tenant_id=workflow_provider.tenant_id) | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |             if controller_tools is None or len(controller_tools) == 0: | 
					
						
							|  |  |  |                 raise ToolProviderNotFoundError(f"workflow provider {provider_id} not found") | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             return cast( | 
					
						
							|  |  |  |                 WorkflowTool, | 
					
						
							|  |  |  |                 controller.get_tools(tenant_id=workflow_provider.tenant_id)[0].fork_tool_runtime( | 
					
						
							|  |  |  |                     runtime=ToolRuntime( | 
					
						
							|  |  |  |                         tenant_id=tenant_id, | 
					
						
							|  |  |  |                         credentials={}, | 
					
						
							|  |  |  |                         invoke_from=invoke_from, | 
					
						
							|  |  |  |                         tool_invoke_from=tool_invoke_from, | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                 ), | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         elif provider_type == ToolProviderType.APP: | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             raise NotImplementedError("app provider not implemented") | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         elif provider_type == ToolProviderType.PLUGIN: | 
					
						
							|  |  |  |             return cls.get_plugin_provider(provider_id, tenant_id).get_tool(tool_name) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             raise ToolProviderNotFoundError(f"provider type {provider_type.value} not found") | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |     def get_agent_tool_runtime( | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         cls, | 
					
						
							|  |  |  |         tenant_id: str, | 
					
						
							|  |  |  |         app_id: str, | 
					
						
							|  |  |  |         agent_tool: AgentToolEntity, | 
					
						
							|  |  |  |         invoke_from: InvokeFrom = InvokeFrom.DEBUGGER, | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |     ) -> Tool: | 
					
						
							| 
									
										
										
										
											2024-03-08 20:31:13 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         get the agent tool runtime | 
					
						
							| 
									
										
										
										
											2024-03-08 20:31:13 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         tool_entity = cls.get_tool_runtime( | 
					
						
							| 
									
										
										
										
											2024-06-05 00:13:04 +08:00
										 |  |  |             provider_type=agent_tool.provider_type, | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |             provider_id=agent_tool.provider_id, | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |             tool_name=agent_tool.tool_name, | 
					
						
							| 
									
										
										
										
											2024-03-08 20:31:13 +08:00
										 |  |  |             tenant_id=tenant_id, | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |             invoke_from=invoke_from, | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             tool_invoke_from=ToolInvokeFrom.AGENT, | 
					
						
							| 
									
										
										
										
											2024-03-08 20:31:13 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  |         runtime_parameters = {} | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         parameters = tool_entity.get_merged_runtime_parameters() | 
					
						
							| 
									
										
										
										
											2024-03-08 20:31:13 +08:00
										 |  |  |         for parameter in parameters: | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |             # check file types | 
					
						
							| 
									
										
										
										
											2024-10-28 16:52:57 +08:00
										 |  |  |             if ( | 
					
						
							|  |  |  |                 parameter.type | 
					
						
							|  |  |  |                 in { | 
					
						
							|  |  |  |                     ToolParameter.ToolParameterType.SYSTEM_FILES, | 
					
						
							|  |  |  |                     ToolParameter.ToolParameterType.FILE, | 
					
						
							|  |  |  |                     ToolParameter.ToolParameterType.FILES, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 and parameter.required | 
					
						
							|  |  |  |             ): | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |                 raise ValueError(f"file type parameter {parameter.name} not supported in agent") | 
					
						
							| 
									
										
										
										
											2024-06-05 00:13:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-08 20:31:13 +08:00
										 |  |  |             if parameter.form == ToolParameter.ToolParameterForm.FORM: | 
					
						
							|  |  |  |                 # save tool parameter to tool entity memory | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                 value = parameter.init_frontend_parameter(agent_tool.tool_parameters.get(parameter.name)) | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                 runtime_parameters[parameter.name] = value | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-08 20:31:13 +08:00
										 |  |  |         # decrypt runtime parameters | 
					
						
							|  |  |  |         encryption_manager = ToolParameterConfigurationManager( | 
					
						
							|  |  |  |             tenant_id=tenant_id, | 
					
						
							|  |  |  |             tool_runtime=tool_entity, | 
					
						
							|  |  |  |             provider_name=agent_tool.provider_id, | 
					
						
							|  |  |  |             provider_type=agent_tool.provider_type, | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             identity_id=f"AGENT.{app_id}", | 
					
						
							| 
									
										
										
										
											2024-03-08 20:31:13 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  |         runtime_parameters = encryption_manager.decrypt_tool_parameters(runtime_parameters) | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |         if tool_entity.runtime is None or tool_entity.runtime.runtime_parameters is None: | 
					
						
							|  |  |  |             raise ValueError("runtime not found or runtime parameters not found") | 
					
						
							| 
									
										
										
										
											2024-03-08 20:31:13 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         tool_entity.runtime.runtime_parameters.update(runtime_parameters) | 
					
						
							|  |  |  |         return tool_entity | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |     def get_workflow_tool_runtime( | 
					
						
							|  |  |  |         cls, | 
					
						
							|  |  |  |         tenant_id: str, | 
					
						
							|  |  |  |         app_id: str, | 
					
						
							|  |  |  |         node_id: str, | 
					
						
							|  |  |  |         workflow_tool: "ToolEntity", | 
					
						
							|  |  |  |         invoke_from: InvokeFrom = InvokeFrom.DEBUGGER, | 
					
						
							|  |  |  |     ) -> Tool: | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         get the workflow tool runtime | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         tool_runtime = cls.get_tool_runtime( | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |             provider_type=workflow_tool.provider_type, | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |             provider_id=workflow_tool.provider_id, | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |             tool_name=workflow_tool.tool_name, | 
					
						
							|  |  |  |             tenant_id=tenant_id, | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |             invoke_from=invoke_from, | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             tool_invoke_from=ToolInvokeFrom.WORKFLOW, | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  |         runtime_parameters = {} | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         parameters = tool_runtime.get_merged_runtime_parameters() | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for parameter in parameters: | 
					
						
							|  |  |  |             # save tool parameter to tool entity memory | 
					
						
							|  |  |  |             if parameter.form == ToolParameter.ToolParameterForm.FORM: | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                 value = parameter.init_frontend_parameter(workflow_tool.tool_configurations.get(parameter.name)) | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                 runtime_parameters[parameter.name] = value | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # decrypt runtime parameters | 
					
						
							|  |  |  |         encryption_manager = ToolParameterConfigurationManager( | 
					
						
							|  |  |  |             tenant_id=tenant_id, | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             tool_runtime=tool_runtime, | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |             provider_name=workflow_tool.provider_id, | 
					
						
							|  |  |  |             provider_type=workflow_tool.provider_type, | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             identity_id=f"WORKFLOW.{app_id}.{node_id}", | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if runtime_parameters: | 
					
						
							|  |  |  |             runtime_parameters = encryption_manager.decrypt_tool_parameters(runtime_parameters) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         tool_runtime.runtime.runtime_parameters.update(runtime_parameters) | 
					
						
							|  |  |  |         return tool_runtime | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def get_tool_runtime_from_plugin( | 
					
						
							|  |  |  |         cls, | 
					
						
							|  |  |  |         tool_type: ToolProviderType, | 
					
						
							|  |  |  |         tenant_id: str, | 
					
						
							|  |  |  |         provider: str, | 
					
						
							|  |  |  |         tool_name: str, | 
					
						
							|  |  |  |         tool_parameters: dict[str, Any], | 
					
						
							|  |  |  |     ) -> Tool: | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         get tool runtime from plugin | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         tool_entity = cls.get_tool_runtime( | 
					
						
							|  |  |  |             provider_type=tool_type, | 
					
						
							|  |  |  |             provider_id=provider, | 
					
						
							|  |  |  |             tool_name=tool_name, | 
					
						
							|  |  |  |             tenant_id=tenant_id, | 
					
						
							|  |  |  |             invoke_from=InvokeFrom.SERVICE_API, | 
					
						
							|  |  |  |             tool_invoke_from=ToolInvokeFrom.PLUGIN, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         runtime_parameters = {} | 
					
						
							|  |  |  |         parameters = tool_entity.get_merged_runtime_parameters() | 
					
						
							|  |  |  |         for parameter in parameters: | 
					
						
							|  |  |  |             if parameter.form == ToolParameter.ToolParameterForm.FORM: | 
					
						
							|  |  |  |                 # save tool parameter to tool entity memory | 
					
						
							|  |  |  |                 value = parameter.init_frontend_parameter(tool_parameters.get(parameter.name)) | 
					
						
							|  |  |  |                 runtime_parameters[parameter.name] = value | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         tool_entity.runtime.runtime_parameters.update(runtime_parameters) | 
					
						
							|  |  |  |         return tool_entity | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     def get_hardcoded_provider_icon(cls, provider: str) -> tuple[str, str]: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         get the absolute path of the icon of the hardcoded provider | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :param provider: the name of the provider | 
					
						
							|  |  |  |         :return: the absolute path of the icon, the mime type of the icon | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         # get provider | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         provider_controller = cls.get_hardcoded_provider(provider) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         absolute_path = path.join( | 
					
						
							|  |  |  |             path.dirname(path.realpath(__file__)), | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             "builtin_tool", | 
					
						
							|  |  |  |             "providers", | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             provider, | 
					
						
							|  |  |  |             "_assets", | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             provider_controller.entity.identity.icon, | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         # check if the icon exists | 
					
						
							|  |  |  |         if not path.exists(absolute_path): | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             raise ToolProviderNotFoundError(f"builtin provider {provider} icon not found") | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         # get the mime type | 
					
						
							|  |  |  |         mime_type, _ = mimetypes.guess_type(absolute_path) | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         mime_type = mime_type or "application/octet-stream" | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return absolute_path, mime_type | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     def list_hardcoded_providers(cls): | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         # use cache first | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         if cls._builtin_providers_loaded: | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             yield from list(cls._hardcoded_providers.values()) | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |             return | 
					
						
							| 
									
										
										
										
											2024-07-06 09:54:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         with cls._builtin_provider_lock: | 
					
						
							|  |  |  |             if cls._builtin_providers_loaded: | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                 yield from list(cls._hardcoded_providers.values()) | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2024-07-06 09:54:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             yield from cls._list_hardcoded_providers() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def list_plugin_providers(cls, tenant_id: str) -> list[PluginToolProviderController]: | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         list all the plugin providers | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         manager = PluginToolManager() | 
					
						
							|  |  |  |         provider_entities = manager.fetch_tool_providers(tenant_id) | 
					
						
							|  |  |  |         return [ | 
					
						
							|  |  |  |             PluginToolProviderController( | 
					
						
							|  |  |  |                 entity=provider.declaration, | 
					
						
							|  |  |  |                 plugin_id=provider.plugin_id, | 
					
						
							|  |  |  |                 plugin_unique_identifier=provider.plugin_unique_identifier, | 
					
						
							|  |  |  |                 tenant_id=tenant_id, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             for provider in provider_entities | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def list_builtin_providers( | 
					
						
							|  |  |  |         cls, tenant_id: str | 
					
						
							|  |  |  |     ) -> Generator[BuiltinToolProviderController | PluginToolProviderController, None, None]: | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         list all the builtin providers | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         yield from cls.list_hardcoded_providers() | 
					
						
							|  |  |  |         # get plugin providers | 
					
						
							|  |  |  |         yield from cls.list_plugin_providers(tenant_id) | 
					
						
							| 
									
										
										
										
											2024-07-06 09:54:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     def _list_hardcoded_providers(cls) -> Generator[BuiltinToolProviderController, None, None]: | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         list all the builtin providers | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         for provider_path in listdir(path.join(path.dirname(path.realpath(__file__)), "builtin_tool", "providers")): | 
					
						
							|  |  |  |             if provider_path.startswith("__"): | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |                 continue | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             if path.isdir(path.join(path.dirname(path.realpath(__file__)), "builtin_tool", "providers", provider_path)): | 
					
						
							|  |  |  |                 if provider_path.startswith("__"): | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |                     continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # init provider | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                 try: | 
					
						
							|  |  |  |                     provider_class = load_single_subclass_from_source( | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                         module_name=f"core.tools.builtin_tool.providers.{provider_path}.{provider_path}", | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |                         script_path=path.join( | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                             path.dirname(path.realpath(__file__)), | 
					
						
							|  |  |  |                             "builtin_tool", | 
					
						
							|  |  |  |                             "providers", | 
					
						
							|  |  |  |                             provider_path, | 
					
						
							|  |  |  |                             f"{provider_path}.py", | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |                         ), | 
					
						
							|  |  |  |                         parent_type=BuiltinToolProviderController, | 
					
						
							|  |  |  |                     ) | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                     provider: BuiltinToolProviderController = provider_class() | 
					
						
							|  |  |  |                     cls._hardcoded_providers[provider.entity.identity.name] = provider | 
					
						
							|  |  |  |                     for tool in provider.get_tools(): | 
					
						
							|  |  |  |                         cls._builtin_tools_labels[tool.entity.identity.name] = tool.entity.identity.label | 
					
						
							|  |  |  |                     yield provider | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 except Exception: | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |                     logger.exception(f"load builtin provider {provider_path}") | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |                     continue | 
					
						
							|  |  |  |         # set builtin providers loaded | 
					
						
							|  |  |  |         cls._builtin_providers_loaded = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     def load_hardcoded_providers_cache(cls): | 
					
						
							|  |  |  |         for _ in cls.list_hardcoded_providers(): | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     def clear_hardcoded_providers_cache(cls): | 
					
						
							|  |  |  |         cls._hardcoded_providers = {} | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         cls._builtin_providers_loaded = False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def get_tool_label(cls, tool_name: str) -> Union[I18nObject, None]: | 
					
						
							| 
									
										
										
										
											2024-01-24 20:14:45 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         get the tool label | 
					
						
							| 
									
										
										
										
											2024-01-24 20:14:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :param tool_name: the name of the tool | 
					
						
							| 
									
										
										
										
											2024-01-24 20:14:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :return: the label of the tool | 
					
						
							| 
									
										
										
										
											2024-01-24 20:14:45 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         if len(cls._builtin_tools_labels) == 0: | 
					
						
							| 
									
										
										
										
											2024-01-24 20:14:45 +08:00
										 |  |  |             # init the builtin providers | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             cls.load_hardcoded_providers_cache() | 
					
						
							| 
									
										
										
										
											2024-01-24 20:14:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         if tool_name not in cls._builtin_tools_labels: | 
					
						
							| 
									
										
										
										
											2024-01-24 20:14:45 +08:00
										 |  |  |             return None | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         return cls._builtin_tools_labels[tool_name] | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     def list_providers_from_api( | 
					
						
							|  |  |  |         cls, user_id: str, tenant_id: str, typ: ToolProviderTypeApiLiteral | 
					
						
							|  |  |  |     ) -> list[ToolProviderApiEntity]: | 
					
						
							|  |  |  |         result_providers: dict[str, ToolProviderApiEntity] = {} | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |         filters = [] | 
					
						
							|  |  |  |         if not typ: | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             filters.extend(["builtin", "api", "workflow"]) | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |         else: | 
					
						
							|  |  |  |             filters.append(typ) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |         with db.session.no_autoflush: | 
					
						
							|  |  |  |             if "builtin" in filters: | 
					
						
							|  |  |  |                 # get builtin providers | 
					
						
							|  |  |  |                 builtin_providers = cls.list_builtin_providers(tenant_id) | 
					
						
							| 
									
										
										
										
											2024-06-05 00:13:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |                 # get db builtin providers | 
					
						
							|  |  |  |                 db_builtin_providers: list[BuiltinToolProvider] = ( | 
					
						
							|  |  |  |                     db.session.query(BuiltinToolProvider).filter(BuiltinToolProvider.tenant_id == tenant_id).all() | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |                 ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |                 # rewrite db_builtin_providers | 
					
						
							|  |  |  |                 for db_provider in db_builtin_providers: | 
					
						
							|  |  |  |                     tool_provider_id = str(ToolProviderID(db_provider.provider)) | 
					
						
							|  |  |  |                     db_provider.provider = tool_provider_id | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 def find_db_builtin_provider(provider): | 
					
						
							|  |  |  |                     return next((x for x in db_builtin_providers if x.provider == provider), None) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 # append builtin providers | 
					
						
							|  |  |  |                 for provider in builtin_providers: | 
					
						
							|  |  |  |                     # handle include, exclude | 
					
						
							|  |  |  |                     if is_filtered( | 
					
						
							|  |  |  |                         include_set=cast(set[str], dify_config.POSITION_TOOL_INCLUDES_SET), | 
					
						
							|  |  |  |                         exclude_set=cast(set[str], dify_config.POSITION_TOOL_EXCLUDES_SET), | 
					
						
							|  |  |  |                         data=provider, | 
					
						
							|  |  |  |                         name_func=lambda x: x.identity.name, | 
					
						
							|  |  |  |                     ): | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     user_provider = ToolTransformService.builtin_provider_to_user_provider( | 
					
						
							|  |  |  |                         provider_controller=provider, | 
					
						
							|  |  |  |                         db_provider=find_db_builtin_provider(provider.entity.identity.name), | 
					
						
							|  |  |  |                         decrypt_credentials=False, | 
					
						
							|  |  |  |                     ) | 
					
						
							| 
									
										
										
										
											2024-06-05 00:13:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |                     if isinstance(provider, PluginToolProviderController): | 
					
						
							|  |  |  |                         result_providers[f"plugin_provider.{user_provider.name}"] = user_provider | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         result_providers[f"builtin_provider.{user_provider.name}"] = user_provider | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |             # get db api providers | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |             if "api" in filters: | 
					
						
							|  |  |  |                 db_api_providers: list[ApiToolProvider] = ( | 
					
						
							|  |  |  |                     db.session.query(ApiToolProvider).filter(ApiToolProvider.tenant_id == tenant_id).all() | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |                 ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |                 api_provider_controllers: list[dict[str, Any]] = [ | 
					
						
							|  |  |  |                     {"provider": provider, "controller": ToolTransformService.api_provider_to_controller(provider)} | 
					
						
							|  |  |  |                     for provider in db_api_providers | 
					
						
							|  |  |  |                 ] | 
					
						
							| 
									
										
										
										
											2024-06-05 00:13:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |                 # get labels | 
					
						
							|  |  |  |                 labels = ToolLabelManager.get_tools_labels([x["controller"] for x in api_provider_controllers]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 for api_provider_controller in api_provider_controllers: | 
					
						
							|  |  |  |                     user_provider = ToolTransformService.api_provider_to_user_provider( | 
					
						
							|  |  |  |                         provider_controller=api_provider_controller["controller"], | 
					
						
							|  |  |  |                         db_provider=api_provider_controller["provider"], | 
					
						
							|  |  |  |                         decrypt_credentials=False, | 
					
						
							|  |  |  |                         labels=labels.get(api_provider_controller["controller"].provider_id, []), | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |                     ) | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |                     result_providers[f"api_provider.{user_provider.name}"] = user_provider | 
					
						
							| 
									
										
										
										
											2024-06-05 00:13:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |             if "workflow" in filters: | 
					
						
							|  |  |  |                 # get workflow providers | 
					
						
							|  |  |  |                 workflow_providers: list[WorkflowToolProvider] = ( | 
					
						
							|  |  |  |                     db.session.query(WorkflowToolProvider).filter(WorkflowToolProvider.tenant_id == tenant_id).all() | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |                 workflow_provider_controllers: list[WorkflowToolProviderController] = [] | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |                 for workflow_provider in workflow_providers: | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |                     try: | 
					
						
							|  |  |  |                         workflow_provider_controllers.append( | 
					
						
							| 
									
										
										
										
											2025-05-21 15:38:03 +08:00
										 |  |  |                             ToolTransformService.workflow_provider_to_controller(db_provider=workflow_provider) | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  |                         ) | 
					
						
							|  |  |  |                     except Exception: | 
					
						
							|  |  |  |                         # app has been deleted | 
					
						
							|  |  |  |                         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 labels = ToolLabelManager.get_tools_labels( | 
					
						
							|  |  |  |                     [cast(ToolProviderController, controller) for controller in workflow_provider_controllers] | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2025-02-25 12:33:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 for provider_controller in workflow_provider_controllers: | 
					
						
							|  |  |  |                     user_provider = ToolTransformService.workflow_provider_to_user_provider( | 
					
						
							|  |  |  |                         provider_controller=provider_controller, | 
					
						
							|  |  |  |                         labels=labels.get(provider_controller.provider_id, []), | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                     result_providers[f"workflow_provider.{user_provider.name}"] = user_provider | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return BuiltinToolProviderSort.sort(list(result_providers.values())) | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |     def get_api_provider_controller( | 
					
						
							|  |  |  |         cls, tenant_id: str, provider_id: str | 
					
						
							|  |  |  |     ) -> tuple[ApiToolProviderController, dict[str, Any]]: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         get the api provider | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-31 13:19:15 +08:00
										 |  |  |         :param tenant_id: the id of the tenant | 
					
						
							|  |  |  |         :param provider_id: the id of the provider | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :return: the provider controller, the credentials | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         provider: ApiToolProvider | None = ( | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             db.session.query(ApiToolProvider) | 
					
						
							|  |  |  |             .filter( | 
					
						
							|  |  |  |                 ApiToolProvider.id == provider_id, | 
					
						
							|  |  |  |                 ApiToolProvider.tenant_id == tenant_id, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             .first() | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if provider is None: | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             raise ToolProviderNotFoundError(f"api provider {provider_id} not found") | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |         controller = ApiToolProviderController.from_db( | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |             provider, | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             ApiProviderAuthType.API_KEY if provider.credentials["auth_type"] == "api_key" else ApiProviderAuthType.NONE, | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  |         controller.load_bundled_tools(provider.tools) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return controller, provider.credentials | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def user_get_api_provider(cls, provider: str, tenant_id: str) -> dict: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         get api provider | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |             get tool provider | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-11-11 21:50:32 +08:00
										 |  |  |         provider_name = provider | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         provider_obj: ApiToolProvider | None = ( | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             db.session.query(ApiToolProvider) | 
					
						
							|  |  |  |             .filter( | 
					
						
							|  |  |  |                 ApiToolProvider.tenant_id == tenant_id, | 
					
						
							|  |  |  |                 ApiToolProvider.name == provider, | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             .first() | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         if provider_obj is None: | 
					
						
							| 
									
										
										
										
											2024-11-11 21:50:32 +08:00
										 |  |  |             raise ValueError(f"you have not added provider {provider_name}") | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         try: | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             credentials = json.loads(provider_obj.credentials_str) or {} | 
					
						
							|  |  |  |         except Exception: | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |             credentials = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # package tool provider controller | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |         controller = ApiToolProviderController.from_db( | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             provider_obj, | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |             ApiProviderAuthType.API_KEY if credentials["auth_type"] == "api_key" else ApiProviderAuthType.NONE, | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  |         # init tool configuration | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         tool_configuration = ProviderConfigEncrypter( | 
					
						
							|  |  |  |             tenant_id=tenant_id, | 
					
						
							|  |  |  |             config=[x.to_basic_provider_config() for x in controller.get_credentials_schema()], | 
					
						
							|  |  |  |             provider_type=controller.provider_type.value, | 
					
						
							|  |  |  |             provider_identity=controller.entity.identity.name, | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         decrypted_credentials = tool_configuration.decrypt(credentials) | 
					
						
							| 
									
										
										
										
											2024-01-24 12:00:34 +08:00
										 |  |  |         masked_credentials = tool_configuration.mask_tool_credentials(decrypted_credentials) | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             icon = json.loads(provider_obj.icon) | 
					
						
							|  |  |  |         except Exception: | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |             icon = {"background": "#252525", "content": "\ud83d\ude01"} | 
					
						
							| 
									
										
										
										
											2024-01-23 19:58:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-27 22:01:11 +08:00
										 |  |  |         # add tool labels | 
					
						
							|  |  |  |         labels = ToolLabelManager.get_tool_labels(controller) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |         return cast( | 
					
						
							|  |  |  |             dict, | 
					
						
							|  |  |  |             jsonable_encoder( | 
					
						
							|  |  |  |                 { | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                     "schema_type": provider_obj.schema_type, | 
					
						
							|  |  |  |                     "schema": provider_obj.schema, | 
					
						
							|  |  |  |                     "tools": provider_obj.tools, | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |                     "icon": icon, | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                     "description": provider_obj.description, | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |                     "credentials": masked_credentials, | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |                     "privacy_policy": provider_obj.privacy_policy, | 
					
						
							|  |  |  |                     "custom_disclaimer": provider_obj.custom_disclaimer, | 
					
						
							| 
									
										
										
										
											2024-12-24 18:38:51 +08:00
										 |  |  |                     "labels": labels, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             ), | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |     def generate_builtin_tool_icon_url(cls, provider_id: str) -> str: | 
					
						
							| 
									
										
										
										
											2025-03-10 14:15:06 +09:00
										 |  |  |         return str( | 
					
						
							|  |  |  |             URL(dify_config.CONSOLE_API_URL or "/") | 
					
						
							|  |  |  |             / "console" | 
					
						
							|  |  |  |             / "api" | 
					
						
							|  |  |  |             / "workspaces" | 
					
						
							|  |  |  |             / "current" | 
					
						
							|  |  |  |             / "tool-provider" | 
					
						
							|  |  |  |             / "builtin" | 
					
						
							|  |  |  |             / provider_id | 
					
						
							|  |  |  |             / "icon" | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def generate_plugin_tool_icon_url(cls, tenant_id: str, filename: str) -> str: | 
					
						
							|  |  |  |         return str( | 
					
						
							| 
									
										
										
										
											2025-03-10 14:15:06 +09:00
										 |  |  |             URL(dify_config.CONSOLE_API_URL or "/") | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |             / "console" | 
					
						
							|  |  |  |             / "api" | 
					
						
							|  |  |  |             / "workspaces" | 
					
						
							|  |  |  |             / "current" | 
					
						
							|  |  |  |             / "plugin" | 
					
						
							|  |  |  |             / "icon" | 
					
						
							|  |  |  |             % {"tenant_id": tenant_id, "filename": filename} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def generate_workflow_tool_icon_url(cls, tenant_id: str, provider_id: str) -> dict: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             workflow_provider: WorkflowToolProvider | None = ( | 
					
						
							|  |  |  |                 db.session.query(WorkflowToolProvider) | 
					
						
							|  |  |  |                 .filter(WorkflowToolProvider.tenant_id == tenant_id, WorkflowToolProvider.id == provider_id) | 
					
						
							|  |  |  |                 .first() | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if workflow_provider is None: | 
					
						
							|  |  |  |                 raise ToolProviderNotFoundError(f"workflow provider {provider_id} not found") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             icon: dict = json.loads(workflow_provider.icon) | 
					
						
							|  |  |  |             return icon | 
					
						
							|  |  |  |         except Exception: | 
					
						
							|  |  |  |             return {"background": "#252525", "content": "\ud83d\ude01"} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def generate_api_tool_icon_url(cls, tenant_id: str, provider_id: str) -> dict: | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             api_provider: ApiToolProvider | None = ( | 
					
						
							|  |  |  |                 db.session.query(ApiToolProvider) | 
					
						
							|  |  |  |                 .filter(ApiToolProvider.tenant_id == tenant_id, ApiToolProvider.id == provider_id) | 
					
						
							|  |  |  |                 .first() | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if api_provider is None: | 
					
						
							|  |  |  |                 raise ToolProviderNotFoundError(f"api provider {provider_id} not found") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             icon: dict = json.loads(api_provider.icon) | 
					
						
							|  |  |  |             return icon | 
					
						
							|  |  |  |         except Exception: | 
					
						
							|  |  |  |             return {"background": "#252525", "content": "\ud83d\ude01"} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def get_tool_icon( | 
					
						
							|  |  |  |         cls, | 
					
						
							|  |  |  |         tenant_id: str, | 
					
						
							|  |  |  |         provider_type: ToolProviderType, | 
					
						
							|  |  |  |         provider_id: str, | 
					
						
							|  |  |  |     ) -> Union[str, dict]: | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         get the tool icon | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-10 17:00:20 +08:00
										 |  |  |         :param tenant_id: the id of the tenant | 
					
						
							|  |  |  |         :param provider_type: the type of the provider | 
					
						
							|  |  |  |         :param provider_id: the id of the provider | 
					
						
							|  |  |  |         :return: | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         provider_type = provider_type | 
					
						
							|  |  |  |         provider_id = provider_id | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  |         if provider_type == ToolProviderType.BUILT_IN: | 
					
						
							|  |  |  |             provider = ToolManager.get_builtin_provider(provider_id, tenant_id) | 
					
						
							|  |  |  |             if isinstance(provider, PluginToolProviderController): | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     return cls.generate_plugin_tool_icon_url(tenant_id, provider.entity.identity.icon) | 
					
						
							|  |  |  |                 except Exception: | 
					
						
							|  |  |  |                     return {"background": "#252525", "content": "\ud83d\ude01"} | 
					
						
							|  |  |  |             return cls.generate_builtin_tool_icon_url(provider_id) | 
					
						
							|  |  |  |         elif provider_type == ToolProviderType.API: | 
					
						
							|  |  |  |             return cls.generate_api_tool_icon_url(tenant_id, provider_id) | 
					
						
							|  |  |  |         elif provider_type == ToolProviderType.WORKFLOW: | 
					
						
							|  |  |  |             return cls.generate_workflow_tool_icon_url(tenant_id, provider_id) | 
					
						
							|  |  |  |         elif provider_type == ToolProviderType.PLUGIN: | 
					
						
							|  |  |  |             provider = ToolManager.get_builtin_provider(provider_id, tenant_id) | 
					
						
							|  |  |  |             if isinstance(provider, PluginToolProviderController): | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     return cls.generate_plugin_tool_icon_url(tenant_id, provider.entity.identity.icon) | 
					
						
							|  |  |  |                 except Exception: | 
					
						
							|  |  |  |                     return {"background": "#252525", "content": "\ud83d\ude01"} | 
					
						
							|  |  |  |             raise ValueError(f"plugin provider {provider_id} not found") | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         else: | 
					
						
							|  |  |  |             raise ValueError(f"provider type {provider_type} not found") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-20 23:16:43 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | ToolManager.load_hardcoded_providers_cache() |