123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- import json
- from datetime import datetime
- from sqlalchemy import or_
- from core.model_runtime.utils.encoders import jsonable_encoder
- from core.tools.entities.api_entities import UserToolProvider
- from core.tools.provider.workflow_tool_provider import WorkflowToolProviderController
- from core.tools.tool_label_manager import ToolLabelManager
- from core.tools.utils.workflow_configuration_sync import WorkflowToolConfigurationUtils
- from extensions.ext_database import db
- from models.model import App
- from models.tools import WorkflowToolProvider
- from models.workflow import Workflow
- from services.tools.tools_transform_service import ToolTransformService
- class WorkflowToolManageService:
- """
- Service class for managing workflow tools.
- """
- @classmethod
- def create_workflow_tool(
- cls,
- user_id: str,
- tenant_id: str,
- workflow_app_id: str,
- name: str,
- label: str,
- icon: dict,
- description: str,
- parameters: list[dict],
- privacy_policy: str = "",
- labels: list[str] = None,
- ) -> dict:
- """
- Create a workflow tool.
- :param user_id: the user id
- :param tenant_id: the tenant id
- :param name: the name
- :param icon: the icon
- :param description: the description
- :param parameters: the parameters
- :param privacy_policy: the privacy policy
- :param labels: labels
- :return: the created tool
- """
- WorkflowToolConfigurationUtils.check_parameter_configurations(parameters)
- # check if the name is unique
- existing_workflow_tool_provider = (
- db.session.query(WorkflowToolProvider)
- .filter(
- WorkflowToolProvider.tenant_id == tenant_id,
- # name or app_id
- or_(WorkflowToolProvider.name == name, WorkflowToolProvider.app_id == workflow_app_id),
- )
- .first()
- )
- if existing_workflow_tool_provider is not None:
- raise ValueError(f"Tool with name {name} or app_id {workflow_app_id} already exists")
- app: App = db.session.query(App).filter(App.id == workflow_app_id, App.tenant_id == tenant_id).first()
- if app is None:
- raise ValueError(f"App {workflow_app_id} not found")
- workflow: Workflow = app.workflow
- if workflow is None:
- raise ValueError(f"Workflow not found for app {workflow_app_id}")
- workflow_tool_provider = WorkflowToolProvider(
- tenant_id=tenant_id,
- user_id=user_id,
- app_id=workflow_app_id,
- name=name,
- label=label,
- icon=json.dumps(icon),
- description=description,
- parameter_configuration=json.dumps(parameters),
- privacy_policy=privacy_policy,
- version=workflow.version,
- )
- try:
- WorkflowToolProviderController.from_db(workflow_tool_provider)
- except Exception as e:
- raise ValueError(str(e))
- db.session.add(workflow_tool_provider)
- db.session.commit()
- return {"result": "success"}
- @classmethod
- def update_workflow_tool(
- cls,
- user_id: str,
- tenant_id: str,
- workflow_tool_id: str,
- name: str,
- label: str,
- icon: dict,
- description: str,
- parameters: list[dict],
- privacy_policy: str = "",
- labels: list[str] = None,
- ) -> dict:
- """
- Update a workflow tool.
- :param user_id: the user id
- :param tenant_id: the tenant id
- :param workflow_tool_id: workflow tool id
- :param name: name
- :param label: label
- :param icon: icon
- :param description: description
- :param parameters: parameters
- :param privacy_policy: privacy policy
- :param labels: labels
- :return: the updated tool
- """
- WorkflowToolConfigurationUtils.check_parameter_configurations(parameters)
- # check if the name is unique
- existing_workflow_tool_provider = (
- db.session.query(WorkflowToolProvider)
- .filter(
- WorkflowToolProvider.tenant_id == tenant_id,
- WorkflowToolProvider.name == name,
- WorkflowToolProvider.id != workflow_tool_id,
- )
- .first()
- )
- if existing_workflow_tool_provider is not None:
- raise ValueError(f"Tool with name {name} already exists")
- workflow_tool_provider: WorkflowToolProvider = (
- db.session.query(WorkflowToolProvider)
- .filter(WorkflowToolProvider.tenant_id == tenant_id, WorkflowToolProvider.id == workflow_tool_id)
- .first()
- )
- if workflow_tool_provider is None:
- raise ValueError(f"Tool {workflow_tool_id} not found")
- app: App = (
- db.session.query(App).filter(App.id == workflow_tool_provider.app_id, App.tenant_id == tenant_id).first()
- )
- if app is None:
- raise ValueError(f"App {workflow_tool_provider.app_id} not found")
- workflow: Workflow = app.workflow
- if workflow is None:
- raise ValueError(f"Workflow not found for app {workflow_tool_provider.app_id}")
- workflow_tool_provider.name = name
- workflow_tool_provider.label = label
- workflow_tool_provider.icon = json.dumps(icon)
- workflow_tool_provider.description = description
- workflow_tool_provider.parameter_configuration = json.dumps(parameters)
- workflow_tool_provider.privacy_policy = privacy_policy
- workflow_tool_provider.version = workflow.version
- workflow_tool_provider.updated_at = datetime.now()
- try:
- WorkflowToolProviderController.from_db(workflow_tool_provider)
- except Exception as e:
- raise ValueError(str(e))
- db.session.add(workflow_tool_provider)
- db.session.commit()
- if labels is not None:
- ToolLabelManager.update_tool_labels(
- ToolTransformService.workflow_provider_to_controller(workflow_tool_provider), labels
- )
- return {"result": "success"}
- @classmethod
- def list_tenant_workflow_tools(cls, user_id: str, tenant_id: str) -> list[UserToolProvider]:
- """
- List workflow tools.
- :param user_id: the user id
- :param tenant_id: the tenant id
- :return: the list of tools
- """
- db_tools = db.session.query(WorkflowToolProvider).filter(WorkflowToolProvider.tenant_id == tenant_id).all()
- tools = []
- for provider in db_tools:
- try:
- tools.append(ToolTransformService.workflow_provider_to_controller(provider))
- except:
- # skip deleted tools
- pass
- labels = ToolLabelManager.get_tools_labels(tools)
- result = []
- for tool in tools:
- user_tool_provider = ToolTransformService.workflow_provider_to_user_provider(
- provider_controller=tool, labels=labels.get(tool.provider_id, [])
- )
- ToolTransformService.repack_provider(user_tool_provider)
- user_tool_provider.tools = [
- ToolTransformService.tool_to_user_tool(
- tool.get_tools(user_id, tenant_id)[0], labels=labels.get(tool.provider_id, [])
- )
- ]
- result.append(user_tool_provider)
- return result
- @classmethod
- def delete_workflow_tool(cls, user_id: str, tenant_id: str, workflow_tool_id: str) -> dict:
- """
- Delete a workflow tool.
- :param user_id: the user id
- :param tenant_id: the tenant id
- :param workflow_app_id: the workflow app id
- """
- db.session.query(WorkflowToolProvider).filter(
- WorkflowToolProvider.tenant_id == tenant_id, WorkflowToolProvider.id == workflow_tool_id
- ).delete()
- db.session.commit()
- return {"result": "success"}
- @classmethod
- def get_workflow_tool_by_tool_id(cls, user_id: str, tenant_id: str, workflow_tool_id: str) -> dict:
- """
- Get a workflow tool.
- :param user_id: the user id
- :param tenant_id: the tenant id
- :param workflow_app_id: the workflow app id
- :return: the tool
- """
- db_tool: WorkflowToolProvider = (
- db.session.query(WorkflowToolProvider)
- .filter(WorkflowToolProvider.tenant_id == tenant_id, WorkflowToolProvider.id == workflow_tool_id)
- .first()
- )
- if db_tool is None:
- raise ValueError(f"Tool {workflow_tool_id} not found")
- workflow_app: App = db.session.query(App).filter(App.id == db_tool.app_id, App.tenant_id == tenant_id).first()
- if workflow_app is None:
- raise ValueError(f"App {db_tool.app_id} not found")
- tool = ToolTransformService.workflow_provider_to_controller(db_tool)
- return {
- "name": db_tool.name,
- "label": db_tool.label,
- "workflow_tool_id": db_tool.id,
- "workflow_app_id": db_tool.app_id,
- "icon": json.loads(db_tool.icon),
- "description": db_tool.description,
- "parameters": jsonable_encoder(db_tool.parameter_configurations),
- "tool": ToolTransformService.tool_to_user_tool(
- tool.get_tools(user_id, tenant_id)[0], labels=ToolLabelManager.get_tool_labels(tool)
- ),
- "synced": workflow_app.workflow.version == db_tool.version,
- "privacy_policy": db_tool.privacy_policy,
- }
- @classmethod
- def get_workflow_tool_by_app_id(cls, user_id: str, tenant_id: str, workflow_app_id: str) -> dict:
- """
- Get a workflow tool.
- :param user_id: the user id
- :param tenant_id: the tenant id
- :param workflow_app_id: the workflow app id
- :return: the tool
- """
- db_tool: WorkflowToolProvider = (
- db.session.query(WorkflowToolProvider)
- .filter(WorkflowToolProvider.tenant_id == tenant_id, WorkflowToolProvider.app_id == workflow_app_id)
- .first()
- )
- if db_tool is None:
- raise ValueError(f"Tool {workflow_app_id} not found")
- workflow_app: App = db.session.query(App).filter(App.id == db_tool.app_id, App.tenant_id == tenant_id).first()
- if workflow_app is None:
- raise ValueError(f"App {db_tool.app_id} not found")
- tool = ToolTransformService.workflow_provider_to_controller(db_tool)
- return {
- "name": db_tool.name,
- "label": db_tool.label,
- "workflow_tool_id": db_tool.id,
- "workflow_app_id": db_tool.app_id,
- "icon": json.loads(db_tool.icon),
- "description": db_tool.description,
- "parameters": jsonable_encoder(db_tool.parameter_configurations),
- "tool": ToolTransformService.tool_to_user_tool(
- tool.get_tools(user_id, tenant_id)[0], labels=ToolLabelManager.get_tool_labels(tool)
- ),
- "synced": workflow_app.workflow.version == db_tool.version,
- "privacy_policy": db_tool.privacy_policy,
- }
- @classmethod
- def list_single_workflow_tools(cls, user_id: str, tenant_id: str, workflow_tool_id: str) -> list[dict]:
- """
- List workflow tool provider tools.
- :param user_id: the user id
- :param tenant_id: the tenant id
- :param workflow_app_id: the workflow app id
- :return: the list of tools
- """
- db_tool: WorkflowToolProvider = (
- db.session.query(WorkflowToolProvider)
- .filter(WorkflowToolProvider.tenant_id == tenant_id, WorkflowToolProvider.id == workflow_tool_id)
- .first()
- )
- if db_tool is None:
- raise ValueError(f"Tool {workflow_tool_id} not found")
- tool = ToolTransformService.workflow_provider_to_controller(db_tool)
- return [
- ToolTransformService.tool_to_user_tool(
- tool.get_tools(user_id, tenant_id)[0], labels=ToolLabelManager.get_tool_labels(tool)
- )
- ]
|