Files
Dom a27b74cf22 v1.0 - Version stable: multi-PC, détection UI-DETR-1, 3 modes exécution
- Frontend v4 accessible sur réseau local (192.168.1.40)
- Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard)
- Ollama GPU fonctionnel
- Self-healing interactif
- Dashboard confiance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 11:23:51 +01:00

200 lines
6.9 KiB
Python

"""
Template Data Models
Contains data models for workflow templates and template parameters.
"""
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Any, Dict, List, Optional
from uuid import uuid4
from .visual_workflow import VisualWorkflow, ParameterType
class TemplateDifficulty(Enum):
"""Difficulty levels for templates"""
BEGINNER = 'beginner'
INTERMEDIATE = 'intermediate'
ADVANCED = 'advanced'
@dataclass
class TemplateParameter:
"""Configurable parameter for a template"""
name: str
type: ParameterType
description: str
default_value: Optional[Any] = None
# Mapping to workflow nodes
node_id: str = ""
parameter_name: str = ""
# UI hints
label: str = ""
placeholder: Optional[str] = None
required: bool = True
def to_dict(self) -> Dict[str, Any]:
return {
'name': self.name,
'type': self.type.value,
'description': self.description,
'default_value': self.default_value,
'node_id': self.node_id,
'parameter_name': self.parameter_name,
'label': self.label,
'placeholder': self.placeholder,
'required': self.required
}
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'TemplateParameter':
return cls(
name=data['name'],
type=ParameterType(data['type']),
description=data['description'],
default_value=data.get('default_value'),
node_id=data.get('node_id', ''),
parameter_name=data.get('parameter_name', ''),
label=data.get('label', ''),
placeholder=data.get('placeholder'),
required=data.get('required', True)
)
@dataclass
class WorkflowTemplate:
"""Template for creating workflows"""
id: str
name: str
description: str
category: str
# Template workflow structure
workflow: VisualWorkflow
# Configurable parameters
parameters: List[TemplateParameter] = field(default_factory=list)
# Metadata
tags: List[str] = field(default_factory=list)
difficulty: TemplateDifficulty = TemplateDifficulty.BEGINNER
estimated_time: int = 5 # minutes
# Usage statistics
usage_count: int = 0
rating: float = 0.0
# Timestamps
created_at: datetime = field(default_factory=datetime.now)
updated_at: datetime = field(default_factory=datetime.now)
created_by: str = "system"
def to_dict(self) -> Dict[str, Any]:
return {
'id': self.id,
'name': self.name,
'description': self.description,
'category': self.category,
'workflow': self.workflow.to_dict(),
'parameters': [p.to_dict() for p in self.parameters],
'tags': self.tags,
'difficulty': self.difficulty.value,
'estimated_time': self.estimated_time,
'usage_count': self.usage_count,
'rating': self.rating,
'created_at': self.created_at.isoformat(),
'updated_at': self.updated_at.isoformat(),
'created_by': self.created_by
}
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'WorkflowTemplate':
return cls(
id=data['id'],
name=data['name'],
description=data['description'],
category=data['category'],
workflow=VisualWorkflow.from_dict(data['workflow']),
parameters=[TemplateParameter.from_dict(p) for p in data.get('parameters', [])],
tags=data.get('tags', []),
difficulty=TemplateDifficulty(data.get('difficulty', 'beginner')),
estimated_time=data.get('estimated_time', 5),
usage_count=data.get('usage_count', 0),
rating=data.get('rating', 0.0),
created_at=datetime.fromisoformat(data.get('created_at', datetime.now().isoformat())),
updated_at=datetime.fromisoformat(data.get('updated_at', datetime.now().isoformat())),
created_by=data.get('created_by', 'system')
)
def instantiate(self, parameters: Dict[str, Any], workflow_name: str, created_by: str = "user") -> VisualWorkflow:
"""Create a new workflow instance from this template"""
# Create a copy of the template workflow
workflow_data = self.workflow.to_dict()
# Generate new IDs
workflow_data['id'] = str(uuid4())
workflow_data['name'] = workflow_name
workflow_data['created_at'] = datetime.now().isoformat()
workflow_data['updated_at'] = datetime.now().isoformat()
workflow_data['created_by'] = created_by
workflow_data['is_template'] = False
# Apply parameter substitutions
for param in self.parameters:
if param.name in parameters:
value = parameters[param.name]
# Find the target node and update its parameter
for node_data in workflow_data['nodes']:
if node_data['id'] == param.node_id:
node_data['parameters'][param.parameter_name] = value
break
# Generate new node and edge IDs to avoid conflicts
node_id_mapping = {}
for i, node_data in enumerate(workflow_data['nodes']):
old_id = node_data['id']
new_id = f"{workflow_data['id']}_node_{i}"
node_id_mapping[old_id] = new_id
node_data['id'] = new_id
# Update edge references
for edge_data in workflow_data['edges']:
edge_data['id'] = str(uuid4())
edge_data['source'] = node_id_mapping.get(edge_data['source'], edge_data['source'])
edge_data['target'] = node_id_mapping.get(edge_data['target'], edge_data['target'])
return VisualWorkflow.from_dict(workflow_data)
def validate(self) -> List[str]:
"""Validate template structure"""
errors = []
# Basic validation
if not self.id:
errors.append("Template ID is required")
if not self.name:
errors.append("Template name is required")
if not self.category:
errors.append("Template category is required")
# Validate workflow
workflow_errors = self.workflow.validate()
errors.extend([f"Workflow: {err}" for err in workflow_errors])
# Validate parameters
node_ids = {node.id for node in self.workflow.nodes}
for param in self.parameters:
if param.node_id and param.node_id not in node_ids:
errors.append(f"Parameter {param.name} references non-existent node {param.node_id}")
return errors
def generate_template_id() -> str:
"""Generate a unique template ID"""
return f"template_{str(uuid4())[:8]}"