# Copyright (c) 2025 Patrick Motsch # All rights reserved. """Workflow Action models: WorkflowActionParameter, WorkflowActionDefinition.""" from typing import Optional, Any, Union, List, Dict, Callable, Awaitable from pydantic import BaseModel, Field from modules.datamodels.datamodelChatbot import ActionResult from modules.shared.frontendTypes import FrontendType from modules.shared.attributeUtils import registerModelLabels class WorkflowActionParameter(BaseModel): """ Parameter schema definition for a workflow action. This defines the structure and UI rendering for a single action parameter, NOT the actual parameter values (those are in ActionDefinition.parameters). """ name: str = Field(description="Parameter name") type: str = Field(description="Python type as string: 'str', 'int', 'bool', 'List[str]', etc.") frontendType: FrontendType = Field(description="UI rendering type (from global FrontendType enum)") frontendOptions: Optional[Union[str, List[str]]] = Field( None, description="Options for select/multiselect/custom types. String reference (e.g., 'user.connection') or list of strings (e.g., ['txt', 'json']). For custom types, this is automatically set to the API endpoint." ) required: bool = Field(False, description="Whether parameter is required") default: Optional[Any] = Field(None, description="Default value") description: str = Field("", description="Parameter description") validation: Optional[Dict[str, Any]] = Field( None, description="Validation rules (e.g., {'min': 1, 'max': 100})" ) class WorkflowActionDefinition(BaseModel): """ Complete schema definition of a workflow action. This defines the metadata, parameters, and execution function for an action. This is different from datamodelWorkflow.ActionDefinition which contains actual execution values (action, actionObjective, parameters with values). This class defines the ACTION SCHEMA, not the execution plan. """ actionId: str = Field( description="Unique action identifier for RBAC (format: 'module.actionName', e.g., 'outlook.readEmails')" ) description: str = Field(description="Action description") parameters: Dict[str, WorkflowActionParameter] = Field( default_factory=dict, description="Parameter schema definitions" ) execute: Optional[Callable] = Field( None, description="Execution function - async function that takes parameters dict and returns ActionResult. Set dynamically." ) category: Optional[str] = Field(None, description="Action category for grouping") tags: List[str] = Field(default_factory=list, description="Tags for search/filtering") dynamicMode: bool = Field(False, description="Whether this action is available in dynamic workflow mode (only tagged actions are visible in action planning and refinement prompts)") # Register model labels for UI registerModelLabels( "WorkflowActionDefinition", {"en": "Workflow Action Definition", "fr": "Définition d'action de workflow"}, { "actionId": {"en": "Action ID", "fr": "ID d'action"}, "description": {"en": "Description", "fr": "Description"}, "parameters": {"en": "Parameters", "fr": "Paramètres"}, "category": {"en": "Category", "fr": "Catégorie"}, "tags": {"en": "Tags", "fr": "Étiquettes"}, "dynamicMode": {"en": "Dynamic Mode", "fr": "Mode dynamique"}, }, ) registerModelLabels( "WorkflowActionParameter", {"en": "Workflow Action Parameter", "fr": "Paramètre d'action de workflow"}, { "name": {"en": "Name", "fr": "Nom"}, "type": {"en": "Type", "fr": "Type"}, "frontendType": {"en": "Frontend Type", "fr": "Type frontend"}, "frontendOptions": {"en": "Frontend Options", "fr": "Options frontend"}, "required": {"en": "Required", "fr": "Requis"}, "default": {"en": "Default", "fr": "Par défaut"}, "description": {"en": "Description", "fr": "Description"}, "validation": {"en": "Validation", "fr": "Validation"}, }, )