# 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.datamodelChat import ActionResult from modules.shared.frontendTypes import FrontendType from modules.shared.i18nRegistry import i18nModel @i18nModel("Workflow-Aktionsparameter") 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", json_schema_extra={"label": "Name"}, ) type: str = Field( description=( "Type reference. Either a primitive ('str', 'int', 'bool', 'float', 'Any', " "'List[str]', 'Dict[str,Any]', …) or a PORT_TYPE_CATALOG schema name " "(e.g. 'ConnectionRef', 'FeatureInstanceRef', 'DocumentList', " "'TrusteeProcessResult'). Catalog types are validated by " "_actionSignatureValidator at startup." ), json_schema_extra={"label": "Typ"}, ) uiHint: Optional[str] = Field( None, description=( "Optional UI rendering hint for adapters. " "Free-form (e.g. 'textarea', 'cron', 'fieldBuilder'). " "Adapters can override; defaults derive from frontendType when absent." ), json_schema_extra={"label": "UI-Hinweis"}, ) frontendType: FrontendType = Field( description="UI rendering type (from global FrontendType enum)", json_schema_extra={"label": "Frontend-Typ"}, ) 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.", json_schema_extra={"label": "Frontend-Optionen"}, ) required: bool = Field( False, description="Whether parameter is required", json_schema_extra={"label": "Pflichtfeld"}, ) default: Optional[Any] = Field( None, description="Default value", json_schema_extra={"label": "Standard"}, ) description: str = Field( "", description="Parameter description", json_schema_extra={"label": "Beschreibung"}, ) validation: Optional[Dict[str, Any]] = Field( None, description="Validation rules (e.g., {'min': 1, 'max': 100})", json_schema_extra={"label": "Validierung"}, ) @i18nModel("Workflow-Aktionsdefinition") 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')", json_schema_extra={"label": "Aktions-ID"}, ) description: str = Field( description="Action description", json_schema_extra={"label": "Beschreibung"}, ) parameters: Dict[str, WorkflowActionParameter] = Field( default_factory=dict, description="Parameter schema definitions", json_schema_extra={"label": "Parameter"}, ) outputType: str = Field( "ActionResult", description=( "PORT_TYPE_CATALOG schema name produced by this action " "(e.g. 'TrusteeProcessResult', 'EmailDraft', 'DocumentList'). " "Defaults to 'ActionResult' for fire-and-forget actions. " "Validated by _actionSignatureValidator at startup." ), json_schema_extra={"label": "Ausgabe-Typ"}, ) execute: Optional[Callable] = Field( None, description="Execution function - async function that takes parameters dict and returns ActionResult. Set dynamically.", json_schema_extra={"label": "Ausfuehrung"}, ) category: Optional[str] = Field( None, description="Action category for grouping", json_schema_extra={"label": "Kategorie"}, ) tags: List[str] = Field( default_factory=list, description="Tags for search/filtering", json_schema_extra={"label": "Tags"}, ) 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)", json_schema_extra={"label": "Dynamischer Modus"}, )