|
import json |
|
import logging |
|
from typing import Optional, Union |
|
|
|
from configs import dify_config |
|
from core.tools.entities.api_entities import UserTool, UserToolProvider |
|
from core.tools.entities.common_entities import I18nObject |
|
from core.tools.entities.tool_bundle import ApiToolBundle |
|
from core.tools.entities.tool_entities import ( |
|
ApiProviderAuthType, |
|
ToolParameter, |
|
ToolProviderCredentials, |
|
ToolProviderType, |
|
) |
|
from core.tools.provider.api_tool_provider import ApiToolProviderController |
|
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController |
|
from core.tools.provider.workflow_tool_provider import WorkflowToolProviderController |
|
from core.tools.tool.tool import Tool |
|
from core.tools.tool.workflow_tool import WorkflowTool |
|
from core.tools.utils.configuration import ToolConfigurationManager |
|
from models.tools import ApiToolProvider, BuiltinToolProvider, WorkflowToolProvider |
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
class ToolTransformService: |
|
@staticmethod |
|
def get_tool_provider_icon_url(provider_type: str, provider_name: str, icon: str) -> Union[str, dict]: |
|
""" |
|
get tool provider icon url |
|
""" |
|
url_prefix = dify_config.CONSOLE_API_URL + "/console/api/workspaces/current/tool-provider/" |
|
|
|
if provider_type == ToolProviderType.BUILT_IN.value: |
|
return url_prefix + "builtin/" + provider_name + "/icon" |
|
elif provider_type in {ToolProviderType.API.value, ToolProviderType.WORKFLOW.value}: |
|
try: |
|
return json.loads(icon) |
|
except: |
|
return {"background": "#252525", "content": "\ud83d\ude01"} |
|
|
|
return "" |
|
|
|
@staticmethod |
|
def repack_provider(provider: Union[dict, UserToolProvider]): |
|
""" |
|
repack provider |
|
|
|
:param provider: the provider dict |
|
""" |
|
if isinstance(provider, dict) and "icon" in provider: |
|
provider["icon"] = ToolTransformService.get_tool_provider_icon_url( |
|
provider_type=provider["type"], provider_name=provider["name"], icon=provider["icon"] |
|
) |
|
elif isinstance(provider, UserToolProvider): |
|
provider.icon = ToolTransformService.get_tool_provider_icon_url( |
|
provider_type=provider.type.value, provider_name=provider.name, icon=provider.icon |
|
) |
|
|
|
@staticmethod |
|
def builtin_provider_to_user_provider( |
|
provider_controller: BuiltinToolProviderController, |
|
db_provider: Optional[BuiltinToolProvider], |
|
decrypt_credentials: bool = True, |
|
) -> UserToolProvider: |
|
""" |
|
convert provider controller to user provider |
|
""" |
|
result = UserToolProvider( |
|
id=provider_controller.identity.name, |
|
author=provider_controller.identity.author, |
|
name=provider_controller.identity.name, |
|
description=I18nObject( |
|
en_US=provider_controller.identity.description.en_US, |
|
zh_Hans=provider_controller.identity.description.zh_Hans, |
|
pt_BR=provider_controller.identity.description.pt_BR, |
|
ja_JP=provider_controller.identity.description.ja_JP, |
|
), |
|
icon=provider_controller.identity.icon, |
|
label=I18nObject( |
|
en_US=provider_controller.identity.label.en_US, |
|
zh_Hans=provider_controller.identity.label.zh_Hans, |
|
pt_BR=provider_controller.identity.label.pt_BR, |
|
ja_JP=provider_controller.identity.label.ja_JP, |
|
), |
|
type=ToolProviderType.BUILT_IN, |
|
masked_credentials={}, |
|
is_team_authorization=False, |
|
tools=[], |
|
labels=provider_controller.tool_labels, |
|
) |
|
|
|
|
|
schema = provider_controller.get_credentials_schema() |
|
for name, value in schema.items(): |
|
result.masked_credentials[name] = ToolProviderCredentials.CredentialsType.default(value.type) |
|
|
|
|
|
if not provider_controller.need_credentials: |
|
result.is_team_authorization = True |
|
result.allow_delete = False |
|
elif db_provider: |
|
result.is_team_authorization = True |
|
|
|
if decrypt_credentials: |
|
credentials = db_provider.credentials |
|
|
|
|
|
tool_configuration = ToolConfigurationManager( |
|
tenant_id=db_provider.tenant_id, provider_controller=provider_controller |
|
) |
|
|
|
decrypted_credentials = tool_configuration.decrypt_tool_credentials(credentials=credentials) |
|
masked_credentials = tool_configuration.mask_tool_credentials(credentials=decrypted_credentials) |
|
|
|
result.masked_credentials = masked_credentials |
|
result.original_credentials = decrypted_credentials |
|
|
|
return result |
|
|
|
@staticmethod |
|
def api_provider_to_controller( |
|
db_provider: ApiToolProvider, |
|
) -> ApiToolProviderController: |
|
""" |
|
convert provider controller to user provider |
|
""" |
|
|
|
controller = ApiToolProviderController.from_db( |
|
db_provider=db_provider, |
|
auth_type=ApiProviderAuthType.API_KEY |
|
if db_provider.credentials["auth_type"] == "api_key" |
|
else ApiProviderAuthType.NONE, |
|
) |
|
|
|
return controller |
|
|
|
@staticmethod |
|
def workflow_provider_to_controller(db_provider: WorkflowToolProvider) -> WorkflowToolProviderController: |
|
""" |
|
convert provider controller to provider |
|
""" |
|
return WorkflowToolProviderController.from_db(db_provider) |
|
|
|
@staticmethod |
|
def workflow_provider_to_user_provider( |
|
provider_controller: WorkflowToolProviderController, labels: Optional[list[str]] = None |
|
): |
|
""" |
|
convert provider controller to user provider |
|
""" |
|
return UserToolProvider( |
|
id=provider_controller.provider_id, |
|
author=provider_controller.identity.author, |
|
name=provider_controller.identity.name, |
|
description=I18nObject( |
|
en_US=provider_controller.identity.description.en_US, |
|
zh_Hans=provider_controller.identity.description.zh_Hans, |
|
), |
|
icon=provider_controller.identity.icon, |
|
label=I18nObject( |
|
en_US=provider_controller.identity.label.en_US, |
|
zh_Hans=provider_controller.identity.label.zh_Hans, |
|
), |
|
type=ToolProviderType.WORKFLOW, |
|
masked_credentials={}, |
|
is_team_authorization=True, |
|
tools=[], |
|
labels=labels or [], |
|
) |
|
|
|
@staticmethod |
|
def api_provider_to_user_provider( |
|
provider_controller: ApiToolProviderController, |
|
db_provider: ApiToolProvider, |
|
decrypt_credentials: bool = True, |
|
labels: Optional[list[str]] = None, |
|
) -> UserToolProvider: |
|
""" |
|
convert provider controller to user provider |
|
""" |
|
username = "Anonymous" |
|
try: |
|
username = db_provider.user.name |
|
except Exception as e: |
|
logger.error(f"failed to get user name for api provider {db_provider.id}: {str(e)}") |
|
|
|
credentials = db_provider.credentials |
|
result = UserToolProvider( |
|
id=db_provider.id, |
|
author=username, |
|
name=db_provider.name, |
|
description=I18nObject( |
|
en_US=db_provider.description, |
|
zh_Hans=db_provider.description, |
|
), |
|
icon=db_provider.icon, |
|
label=I18nObject( |
|
en_US=db_provider.name, |
|
zh_Hans=db_provider.name, |
|
), |
|
type=ToolProviderType.API, |
|
masked_credentials={}, |
|
is_team_authorization=True, |
|
tools=[], |
|
labels=labels or [], |
|
) |
|
|
|
if decrypt_credentials: |
|
|
|
tool_configuration = ToolConfigurationManager( |
|
tenant_id=db_provider.tenant_id, provider_controller=provider_controller |
|
) |
|
|
|
|
|
decrypted_credentials = tool_configuration.decrypt_tool_credentials(credentials=credentials) |
|
masked_credentials = tool_configuration.mask_tool_credentials(credentials=decrypted_credentials) |
|
|
|
result.masked_credentials = masked_credentials |
|
|
|
return result |
|
|
|
@staticmethod |
|
def tool_to_user_tool( |
|
tool: Union[ApiToolBundle, WorkflowTool, Tool], |
|
credentials: Optional[dict] = None, |
|
tenant_id: Optional[str] = None, |
|
labels: Optional[list[str]] = None, |
|
) -> UserTool: |
|
""" |
|
convert tool to user tool |
|
""" |
|
if isinstance(tool, Tool): |
|
|
|
tool = tool.fork_tool_runtime( |
|
runtime={ |
|
"credentials": credentials, |
|
"tenant_id": tenant_id, |
|
} |
|
) |
|
|
|
|
|
parameters = tool.parameters or [] |
|
|
|
runtime_parameters = tool.get_runtime_parameters() or [] |
|
|
|
current_parameters = parameters.copy() |
|
for runtime_parameter in runtime_parameters: |
|
found = False |
|
for index, parameter in enumerate(current_parameters): |
|
if parameter.name == runtime_parameter.name and parameter.form == runtime_parameter.form: |
|
current_parameters[index] = runtime_parameter |
|
found = True |
|
break |
|
|
|
if not found and runtime_parameter.form == ToolParameter.ToolParameterForm.FORM: |
|
current_parameters.append(runtime_parameter) |
|
|
|
return UserTool( |
|
author=tool.identity.author, |
|
name=tool.identity.name, |
|
label=tool.identity.label, |
|
description=tool.description.human, |
|
parameters=current_parameters, |
|
labels=labels, |
|
) |
|
if isinstance(tool, ApiToolBundle): |
|
return UserTool( |
|
author=tool.author, |
|
name=tool.operation_id, |
|
label=I18nObject(en_US=tool.operation_id, zh_Hans=tool.operation_id), |
|
description=I18nObject(en_US=tool.summary or "", zh_Hans=tool.summary or ""), |
|
parameters=tool.parameters, |
|
labels=labels, |
|
) |
|
|