|
@@ -6,6 +6,9 @@ from os import listdir, path
|
|
|
from threading import Lock
|
|
|
from typing import TYPE_CHECKING, Any, Union, cast
|
|
|
|
|
|
+from yarl import URL
|
|
|
+
|
|
|
+import contexts
|
|
|
from core.plugin.entities.plugin import GenericProviderID
|
|
|
from core.plugin.manager.tool import PluginToolManager
|
|
|
from core.tools.__base.tool_runtime import ToolRuntime
|
|
@@ -97,16 +100,26 @@ class ToolManager:
|
|
|
"""
|
|
|
get the plugin provider
|
|
|
"""
|
|
|
- manager = PluginToolManager()
|
|
|
- provider_entity = manager.fetch_tool_provider(tenant_id, provider)
|
|
|
- if not provider_entity:
|
|
|
- raise ToolProviderNotFoundError(f"plugin provider {provider} not found")
|
|
|
+ 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]
|
|
|
|
|
|
- return PluginToolProviderController(
|
|
|
- entity=provider_entity.declaration,
|
|
|
- plugin_id=provider_entity.plugin_id,
|
|
|
- tenant_id=tenant_id,
|
|
|
- )
|
|
|
+ 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,
|
|
|
+ )
|
|
|
+
|
|
|
+ plugin_tool_providers[provider] = controller
|
|
|
+
|
|
|
+ return controller
|
|
|
|
|
|
@classmethod
|
|
|
def get_builtin_tool(cls, provider: str, tool_name: str, tenant_id: str) -> BuiltinTool | PluginTool | None:
|
|
@@ -132,7 +145,7 @@ class ToolManager:
|
|
|
tenant_id: str,
|
|
|
invoke_from: InvokeFrom = InvokeFrom.DEBUGGER,
|
|
|
tool_invoke_from: ToolInvokeFrom = ToolInvokeFrom.AGENT,
|
|
|
- ) -> Union[BuiltinTool, ApiTool, WorkflowTool]:
|
|
|
+ ) -> Union[BuiltinTool, PluginTool, ApiTool, WorkflowTool]:
|
|
|
"""
|
|
|
get the tool runtime
|
|
|
|
|
@@ -260,6 +273,8 @@ class ToolManager:
|
|
|
)
|
|
|
elif provider_type == ToolProviderType.APP:
|
|
|
raise NotImplementedError("app provider not implemented")
|
|
|
+ elif provider_type == ToolProviderType.PLUGIN:
|
|
|
+ return cls.get_plugin_provider(provider_id, tenant_id).get_tool(tool_name)
|
|
|
else:
|
|
|
raise ToolProviderNotFoundError(f"provider type {provider_type.value} not found")
|
|
|
|
|
@@ -477,6 +492,7 @@ class ToolManager:
|
|
|
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
|
|
@@ -758,7 +774,66 @@ class ToolManager:
|
|
|
)
|
|
|
|
|
|
@classmethod
|
|
|
- def get_tool_icon(cls, tenant_id: str, provider_type: ToolProviderType, provider_id: str) -> Union[str, dict]:
|
|
|
+ def generate_builtin_tool_icon_url(cls, provider_id: str) -> str:
|
|
|
+ return (
|
|
|
+ dify_config.CONSOLE_API_URL
|
|
|
+ + "/console/api/workspaces/current/tool-provider/builtin/"
|
|
|
+ + provider_id
|
|
|
+ + "/icon"
|
|
|
+ )
|
|
|
+
|
|
|
+ @classmethod
|
|
|
+ def generate_plugin_tool_icon_url(cls, tenant_id: str, filename: str) -> str:
|
|
|
+ return str(
|
|
|
+ URL(dify_config.CONSOLE_API_URL)
|
|
|
+ / "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")
|
|
|
+
|
|
|
+ return json.loads(workflow_provider.icon)
|
|
|
+ except:
|
|
|
+ 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")
|
|
|
+
|
|
|
+ return json.loads(api_provider.icon)
|
|
|
+ except:
|
|
|
+ return {"background": "#252525", "content": "\ud83d\ude01"}
|
|
|
+
|
|
|
+ @classmethod
|
|
|
+ def get_tool_icon(
|
|
|
+ cls,
|
|
|
+ tenant_id: str,
|
|
|
+ provider_type: ToolProviderType,
|
|
|
+ provider_id: str,
|
|
|
+ ) -> Union[str, dict]:
|
|
|
"""
|
|
|
get the tool icon
|
|
|
|
|
@@ -770,36 +845,25 @@ class ToolManager:
|
|
|
provider_type = provider_type
|
|
|
provider_id = provider_id
|
|
|
if provider_type == ToolProviderType.BUILT_IN:
|
|
|
- return (
|
|
|
- dify_config.CONSOLE_API_URL
|
|
|
- + "/console/api/workspaces/current/tool-provider/builtin/"
|
|
|
- + provider_id
|
|
|
- + "/icon"
|
|
|
- )
|
|
|
+ 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:
|
|
|
+ return {"background": "#252525", "content": "\ud83d\ude01"}
|
|
|
+ return cls.generate_builtin_tool_icon_url(provider_id)
|
|
|
elif provider_type == ToolProviderType.API:
|
|
|
- try:
|
|
|
- api_provider: ApiToolProvider | None = (
|
|
|
- db.session.query(ApiToolProvider)
|
|
|
- .filter(ApiToolProvider.tenant_id == tenant_id, ApiToolProvider.id == provider_id)
|
|
|
- .first()
|
|
|
- )
|
|
|
- if not api_provider:
|
|
|
- raise ValueError("api tool not found")
|
|
|
-
|
|
|
- return json.loads(api_provider.icon)
|
|
|
- except:
|
|
|
- return {"background": "#252525", "content": "\ud83d\ude01"}
|
|
|
+ return cls.generate_api_tool_icon_url(tenant_id, provider_id)
|
|
|
elif provider_type == ToolProviderType.WORKFLOW:
|
|
|
- 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")
|
|
|
-
|
|
|
- return json.loads(workflow_provider.icon)
|
|
|
+ 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:
|
|
|
+ return {"background": "#252525", "content": "\ud83d\ude01"}
|
|
|
+ raise ValueError(f"plugin provider {provider_id} not found")
|
|
|
else:
|
|
|
raise ValueError(f"provider type {provider_type} not found")
|
|
|
|