from typing import Any, Literal, Union from pydantic import BaseModel, validator from core.workflow.entities.base_node_data_entities import BaseNodeData class ToolEntity(BaseModel): provider_id: str provider_type: Literal['builtin', 'api'] provider_name: str # redundancy tool_name: str tool_label: str # redundancy tool_configurations: dict[str, Any] @validator('tool_configurations', pre=True, always=True) def validate_tool_configurations(cls, value, values): if not isinstance(value, dict): raise ValueError('tool_configurations must be a dictionary') for key in values.get('tool_configurations', {}).keys(): value = values.get('tool_configurations', {}).get(key) if not isinstance(value, str | int | float | bool): raise ValueError(f'{key} must be a string') return value class ToolNodeData(BaseNodeData, ToolEntity): class ToolInput(BaseModel): value: Union[Any, list[str]] type: Literal['mixed', 'variable', 'constant'] @validator('type', pre=True, always=True) def check_type(cls, value, values): typ = value value = values.get('value') if typ == 'mixed' and not isinstance(value, str): raise ValueError('value must be a string') elif typ == 'variable': if not isinstance(value, list): raise ValueError('value must be a list') for val in value: if not isinstance(val, str): raise ValueError('value must be a list of strings') elif typ == 'constant' and not isinstance(value, str | int | float | bool): raise ValueError('value must be a string, int, float, or bool') return typ """ Tool Node Schema """ tool_parameters: dict[str, ToolInput]