Validé sur PC Windows (DESKTOP-58D5CAC, 2560x1600) : - 8 clics résolus visuellement (1 anchor_template, 1 som_text_match, 6 som_vlm) - Score moyen 0.75, temps moyen 1.6s - Texte tapé correctement (bonjour, test word, date, email) - 0 retries, 2 actions non vérifiées (OK) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
32 KiB
Design Document - Intégration ActionExecutor/WorkflowPipeline
Vue d'Ensemble
Ce document spécifie le design pour l'intégration complète entre ActionExecutor et WorkflowPipeline dans RPA Vision V3. Cette intégration établit le pipeline d'exécution automatique des workflows, connectant la résolution d'état avec l'exécution d'actions physiques tout en préservant la robustesse et les performances du système.
Architecture
L'architecture d'intégration suit un modèle de pipeline d'exécution unifié qui orchestre tous les composants nécessaires :
┌─────────────────────────────────────────────────────────────────┐
│ Architecture d'Intégration ActionExecutor │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
│ │ WorkflowPipeline│ │ ExecutionEngine │ │ActionExecutor│ │
│ │ Enhanced │ │ Orchestrator │ │ Enhanced │ │
│ │ │ │ │ │ │ │
│ │ • State Match │◄──►│ • Context Mgmt │◄──►│ • Target │ │
│ │ • Action Plan │ │ • Error Recovery│ │ Resolution│ │
│ │ • Flow Control │ │ • Metrics │ │ • Physical │ │
│ │ • Learning │ │ • Audit Trail │ │ Execution │ │
│ └─────────────────┘ └─────────────────┘ └─────────────┘ │
│ │ │ │ │
│ │ │ │ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │
│ │ ExecutionContext│ │ PerformanceOpt │ │ LearningInt │ │
│ │ Manager │ │ Engine │ │ egration │ │
│ │ │ │ │ │ │ │
│ │ • State Tracking│ │ • Cache Mgmt │ │ • Pattern │ │
│ │ • Variable Mgmt │ │ • Resource Opt │ │ Learning │ │
│ │ • History │ │ • Priority Mgmt │ │ • Model │ │
│ │ • Validation │ │ • Adaptive Exec │ │ Update │ │
│ └─────────────────┘ └─────────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Composants et Interfaces
1. ExecutionEngine - Orchestrateur Central
Le cœur de l'intégration qui coordonne tous les composants :
class ExecutionEngine:
def __init__(self, workflow_pipeline: WorkflowPipeline,
action_executor: ActionExecutor,
target_resolver: TargetResolver,
context_manager: ExecutionContextManager,
performance_optimizer: PerformanceOptimizer,
learning_integration: LearningIntegration):
self.workflow_pipeline = workflow_pipeline
self.action_executor = action_executor
self.target_resolver = target_resolver
self.context_manager = context_manager
self.performance_optimizer = performance_optimizer
self.learning_integration = learning_integration
def execute_workflow_step(self, workflow_id: str,
current_state: ScreenState) -> StepExecutionResult:
"""
Exécute une étape complète de workflow avec intégration totale
Pipeline d'exécution:
1. Préparer le contexte d'exécution
2. Matcher l'état actuel avec le workflow
3. Planifier la prochaine action
4. Résoudre la cible si nécessaire
5. Exécuter l'action physique
6. Capturer les résultats et métriques
7. Mettre à jour le contexte et l'apprentissage
8. Gérer les erreurs et récupérations
"""
execution_id = str(uuid.uuid4())
try:
# 1. Préparer le contexte
context = self.context_manager.prepare_execution_context(
workflow_id, current_state, execution_id
)
# 2. Matcher l'état
match_result = self.workflow_pipeline.match_current_state(
current_state, context
)
if not match_result:
return StepExecutionResult.no_match(execution_id, context)
# 3. Planifier l'action
action_plan = self.workflow_pipeline.get_next_action(
workflow_id, match_result.node_id, context
)
if not action_plan:
return StepExecutionResult.workflow_complete(execution_id, context)
# 4. Optimiser l'exécution
optimized_plan = self.performance_optimizer.optimize_execution(
action_plan, current_state, context
)
# 5. Exécuter avec intégration complète
execution_result = self._execute_action_integrated(
optimized_plan, current_state, context
)
# 6. Post-traitement
final_result = self._post_process_execution(
execution_result, context, match_result
)
return final_result
except Exception as e:
return self._handle_execution_error(e, context, execution_id)
def _execute_action_integrated(self, action_plan: ActionPlan,
current_state: ScreenState,
context: ExecutionContext) -> ActionExecutionResult:
"""Exécution intégrée avec résolution de cible et métriques"""
start_time = time.time()
# Résolution de cible si nécessaire
if action_plan.requires_target_resolution:
target_result = self.target_resolver.resolve_target(
action_plan.target_spec, current_state.ui_elements
)
if not target_result:
raise TargetResolutionError(
f"Cannot resolve target for action {action_plan.action_type}"
)
context.resolved_target = target_result
# Exécution physique
action_result = self.action_executor.execute_action(
action_plan.action, current_state, context
)
# Capture des métriques
execution_time = time.time() - start_time
context.add_metric('execution_time', execution_time)
context.add_metric('target_resolution_time',
getattr(context.resolved_target, 'resolution_time', 0))
return ActionExecutionResult(
success=action_result.success,
action_plan=action_plan,
action_result=action_result,
context=context,
execution_time=execution_time
)
2. ExecutionContextManager - Gestion du Contexte
Gère le contexte riche d'exécution avec état, variables et historique :
class ExecutionContextManager:
def __init__(self):
self.context_cache = {}
self.variable_manager = VariableManager()
self.history_tracker = ExecutionHistoryTracker()
def prepare_execution_context(self, workflow_id: str,
current_state: ScreenState,
execution_id: str) -> ExecutionContext:
"""
Prépare un contexte d'exécution complet
Composants du contexte:
- État actuel de l'écran
- Variables du workflow
- Historique des actions
- Métriques de performance
- Métadonnées d'audit
"""
# Récupérer ou créer le contexte du workflow
workflow_context = self.context_cache.get(workflow_id)
if not workflow_context:
workflow_context = self._create_workflow_context(workflow_id)
self.context_cache[workflow_id] = workflow_context
# Créer le contexte d'exécution
execution_context = ExecutionContext(
execution_id=execution_id,
workflow_id=workflow_id,
current_state=current_state,
variables=self.variable_manager.get_variables(workflow_id),
history=self.history_tracker.get_recent_history(workflow_id, limit=10),
workflow_context=workflow_context,
created_at=datetime.now(),
metrics={}
)
# Validation du contexte
self._validate_context_integrity(execution_context)
return execution_context
def update_context_after_execution(self, context: ExecutionContext,
execution_result: ActionExecutionResult) -> None:
"""Met à jour le contexte après exécution"""
# Mettre à jour les variables si modifiées
if execution_result.variable_changes:
self.variable_manager.update_variables(
context.workflow_id, execution_result.variable_changes
)
context.variables.update(execution_result.variable_changes)
# Ajouter à l'historique
self.history_tracker.add_execution(
context.workflow_id, execution_result
)
# Mettre à jour les métriques
context.metrics.update(execution_result.metrics)
# Validation post-exécution
self._validate_context_integrity(context)
def _validate_context_integrity(self, context: ExecutionContext) -> None:
"""Valide l'intégrité du contexte et corrige les incohérences"""
# Vérifier la cohérence des variables
if not self.variable_manager.validate_variables(context.variables):
logger.warning(f"Variable inconsistency detected in {context.execution_id}")
context.variables = self.variable_manager.repair_variables(
context.workflow_id, context.variables
)
# Vérifier la cohérence de l'état
if not self._validate_state_consistency(context.current_state):
logger.warning(f"State inconsistency detected in {context.execution_id}")
context.add_flag('state_inconsistency_detected')
# Vérifier l'historique
if not self.history_tracker.validate_history_sequence(context.history):
logger.warning(f"History inconsistency detected in {context.execution_id}")
context.history = self.history_tracker.repair_history(
context.workflow_id
)
@dataclass
class ExecutionContext:
"""Contexte riche d'exécution"""
execution_id: str
workflow_id: str
current_state: ScreenState
variables: Dict[str, Any]
history: List[ActionExecutionResult]
workflow_context: Dict[str, Any]
created_at: datetime
metrics: Dict[str, float]
resolved_target: Optional[ResolvedTarget] = None
flags: Set[str] = field(default_factory=set)
def add_metric(self, name: str, value: float) -> None:
self.metrics[name] = value
def add_flag(self, flag: str) -> None:
self.flags.add(flag)
def has_flag(self, flag: str) -> bool:
return flag in self.flags
3. RobustnessEngine - Gestion d'Erreurs et Récupération
Système robuste de gestion d'erreurs avec stratégies de récupération :
class RobustnessEngine:
def __init__(self):
self.recovery_strategies = {
TargetNotFoundError: [
SpatialFallbackStrategy(),
SemanticVariantStrategy(),
UIRefreshStrategy()
],
ActionExecutionError: [
RetryWithDelayStrategy(),
AlternativeActionStrategy(),
ContextResetStrategy()
],
InterfaceChangedError: [
DynamicAdaptationStrategy(),
RelearningStrategy(),
FallbackModeStrategy()
]
}
def handle_execution_error(self, error: Exception,
context: ExecutionContext,
action_plan: ActionPlan) -> RecoveryResult:
"""
Gère les erreurs d'exécution avec récupération intelligente
Processus de récupération:
1. Classifier l'erreur
2. Sélectionner les stratégies appropriées
3. Appliquer les stratégies en séquence
4. Évaluer le succès de la récupération
5. Logger pour l'apprentissage
"""
error_type = type(error)
strategies = self.recovery_strategies.get(error_type, [])
recovery_attempts = []
for strategy in strategies:
try:
recovery_result = strategy.attempt_recovery(
error, context, action_plan
)
recovery_attempts.append(recovery_result)
if recovery_result.success:
self._log_successful_recovery(
error, strategy, recovery_result, context
)
return RecoveryResult.success(
strategy=strategy,
result=recovery_result,
attempts=recovery_attempts
)
except Exception as recovery_error:
recovery_attempts.append(RecoveryAttempt.failed(
strategy=strategy,
error=recovery_error
))
# Toutes les récupérations ont échoué
return RecoveryResult.escalate(
original_error=error,
recovery_attempts=recovery_attempts,
context=context
)
def adapt_to_interface_change(self, old_state: ScreenState,
new_state: ScreenState,
context: ExecutionContext) -> AdaptationResult:
"""Adaptation dynamique aux changements d'interface"""
# Analyser les changements
changes = self._analyze_interface_changes(old_state, new_state)
# Adapter le contexte
adapted_context = self._adapt_context_to_changes(context, changes)
# Mettre à jour les stratégies de résolution
updated_strategies = self._update_resolution_strategies(changes)
return AdaptationResult(
adapted_context=adapted_context,
updated_strategies=updated_strategies,
change_summary=changes
)
class SpatialFallbackStrategy(RecoveryStrategy):
def attempt_recovery(self, error: TargetNotFoundError,
context: ExecutionContext,
action_plan: ActionPlan) -> RecoveryAttempt:
"""Récupération par fallback spatial"""
# Essayer des critères spatiaux alternatifs
alternative_specs = self._generate_spatial_alternatives(
action_plan.target_spec
)
for alt_spec in alternative_specs:
target_result = context.target_resolver.resolve_target(
alt_spec, context.current_state.ui_elements
)
if target_result:
return RecoveryAttempt.success(
strategy="spatial_fallback",
recovered_target=target_result,
alternative_spec=alt_spec
)
return RecoveryAttempt.failed(
strategy="spatial_fallback",
reason="No spatial alternatives found"
)
4. PerformanceOptimizer - Optimisation des Performances
Optimisation intelligente des performances avec cache et priorisation :
class PerformanceOptimizer:
def __init__(self):
self.interface_analysis_cache = LRUCache(maxsize=100)
self.action_execution_cache = LRUCache(maxsize=50)
self.roi_priority_manager = ROIPriorityManager()
def optimize_execution(self, action_plan: ActionPlan,
current_state: ScreenState,
context: ExecutionContext) -> OptimizedActionPlan:
"""
Optimise l'exécution d'une action
Optimisations:
- Réutilisation des analyses d'interface
- Cache des résolutions similaires
- Priorisation des zones d'intérêt
- Adaptation aux ressources disponibles
"""
# Vérifier le cache pour des actions similaires
cache_key = self._compute_action_cache_key(action_plan, current_state)
cached_result = self.action_execution_cache.get(cache_key)
if cached_result and self._is_cache_valid(cached_result, current_state):
return OptimizedActionPlan.from_cache(cached_result, action_plan)
# Optimiser l'analyse d'interface
optimized_analysis = self._optimize_interface_analysis(
current_state, action_plan.target_spec
)
# Prioriser les zones d'intérêt
prioritized_regions = self.roi_priority_manager.prioritize_regions(
current_state, action_plan
)
# Adapter aux ressources disponibles
resource_adapted_plan = self._adapt_to_resources(
action_plan, context.get_available_resources()
)
optimized_plan = OptimizedActionPlan(
original_plan=action_plan,
optimized_analysis=optimized_analysis,
prioritized_regions=prioritized_regions,
resource_adaptations=resource_adapted_plan,
cache_key=cache_key
)
# Mettre en cache pour les futures utilisations
self.action_execution_cache.put(cache_key, optimized_plan)
return optimized_plan
def _optimize_interface_analysis(self, current_state: ScreenState,
target_spec: TargetSpec) -> OptimizedAnalysis:
"""Optimise l'analyse d'interface avec réutilisation"""
state_signature = self._compute_state_signature(current_state)
# Vérifier le cache d'analyse
cached_analysis = self.interface_analysis_cache.get(state_signature)
if cached_analysis:
return cached_analysis.adapt_for_target(target_spec)
# Nouvelle analyse optimisée
analysis = InterfaceAnalyzer.analyze_optimized(
current_state, target_spec
)
self.interface_analysis_cache.put(state_signature, analysis)
return analysis
def _adapt_to_resources(self, action_plan: ActionPlan,
available_resources: ResourceInfo) -> ResourceAdaptedPlan:
"""Adapte le plan aux ressources disponibles"""
if available_resources.memory_pressure > 0.8:
# Réduire la complexité de l'analyse
return action_plan.with_reduced_complexity()
if available_resources.cpu_usage > 0.9:
# Utiliser des stratégies moins intensives
return action_plan.with_lightweight_strategies()
if available_resources.gpu_available:
# Utiliser l'accélération GPU si disponible
return action_plan.with_gpu_acceleration()
return action_plan # Pas d'adaptation nécessaire
Modèles de Données
StepExecutionResult Complet
@dataclass
class StepExecutionResult:
"""Résultat complet d'exécution d'étape"""
execution_id: str
workflow_id: str
success: bool
step_type: str
# Résultats d'exécution
action_executed: Optional[ActionPlan] = None
target_resolved: Optional[ResolvedTarget] = None
action_result: Optional[ActionResult] = None
# Contexte et état
execution_context: Optional[ExecutionContext] = None
state_before: Optional[ScreenState] = None
state_after: Optional[ScreenState] = None
# Gestion d'erreurs
error: Optional[Exception] = None
recovery_applied: Optional[RecoveryResult] = None
# Métriques et performance
performance_metrics: Dict[str, float] = field(default_factory=dict)
execution_time: float = 0.0
# Apprentissage et audit
learning_data: Dict[str, Any] = field(default_factory=dict)
audit_trail: List[AuditEntry] = field(default_factory=list)
# Métadonnées
created_at: datetime = field(default_factory=datetime.now)
correlation_id: str = field(default_factory=lambda: str(uuid.uuid4()))
@classmethod
def success(cls, execution_id: str, workflow_id: str,
action_result: ActionExecutionResult,
context: ExecutionContext) -> 'StepExecutionResult':
return cls(
execution_id=execution_id,
workflow_id=workflow_id,
success=True,
step_type="action_execution",
action_executed=action_result.action_plan,
target_resolved=context.resolved_target,
action_result=action_result.action_result,
execution_context=context,
performance_metrics=action_result.metrics,
execution_time=action_result.execution_time
)
@classmethod
def no_match(cls, execution_id: str, context: ExecutionContext) -> 'StepExecutionResult':
return cls(
execution_id=execution_id,
workflow_id=context.workflow_id,
success=False,
step_type="state_matching",
execution_context=context,
audit_trail=[AuditEntry.no_match(context.current_state)]
)
Propriétés de Correction
Une propriété est une caractéristique ou un comportement qui doit être vrai dans toutes les exécutions valides d'un système - essentiellement, une déclaration formelle sur ce que le système doit faire. Les propriétés servent de pont entre les spécifications lisibles par l'homme et les garanties de correction vérifiables par machine.
Propriété 1: Intégration WorkflowPipeline-ActionExecutor
Pour toute action identifiée par WorkflowPipeline, ActionExecutor doit être utilisé pour l'exécution Valide: Exigences 1.1, 1.2
Propriété 2: Ordre de résolution de cible
Pour toute action nécessitant une résolution de cible, TargetResolver doit être appelé avant ActionExecutor Valide: Exigences 1.2
Propriété 3: Capture complète des résultats
Pour toute exécution d'action complétée, le résultat doit contenir toutes les métadonnées requises Valide: Exigences 1.3
Propriété 4: Gestion des échecs d'action
Pour tout échec d'action, les stratégies de récupération appropriées doivent être appliquées Valide: Exigences 1.4, 3.1
Propriété 5: Progression automatique du workflow
Pour tout workflow en cours, les étapes doivent s'enchaîner automatiquement après succès Valide: Exigences 1.5
Propriété 6: Contexte d'écran disponible
Pour toute action exécutée, l'état actuel de l'écran doit être disponible dans le contexte Valide: Exigences 2.1
Propriété 7: Accès aux variables du workflow
Pour toute action nécessitant des variables, elles doivent être accessibles dans le contexte Valide: Exigences 2.2
Propriété 8: Historique des actions maintenu
Pour toute exécution d'action, l'historique des actions précédentes doit être disponible Valide: Exigences 2.3
Propriété 9: Mise à jour du contexte
Pour toute action modifiant l'état, le contexte doit être mis à jour pour les actions suivantes Valide: Exigences 2.4
Propriété 10: Détection d'incohérences du contexte
Pour tout contexte corrompu détecté, des corrections doivent être appliquées automatiquement Valide: Exigences 2.5
Propriété 11: Récupération automatique des échecs temporaires
Pour tout échec temporaire d'action, une tentative de récupération automatique doit être effectuée Valide: Exigences 3.1
Propriété 12: Stratégies alternatives de résolution
Pour tout échec de résolution de cible, des stratégies alternatives doivent être tentées Valide: Exigences 3.2
Propriété 13: Adaptation dynamique aux changements d'interface
Pour tout changement d'interface détecté, le système doit s'adapter dynamiquement Valide: Exigences 3.3
Propriété 14: Escalade avec contexte complet
Pour tout échec de récupération, l'escalade doit inclure le contexte complet Valide: Exigences 3.4
Propriété 15: Logging des récupérations réussies
Pour toute récupération réussie, elle doit être loggée pour l'apprentissage Valide: Exigences 3.5
Propriété 16: Mesure du temps de résolution
Pour toute action exécutée, le temps de résolution de cible doit être mesuré Valide: Exigences 4.1
Propriété 17: Mesure du temps d'exécution
Pour toute action exécutée, le temps d'exécution physique doit être mesuré Valide: Exigences 4.2
Propriété 18: Calcul des métriques de succès
Pour toute étape de workflow complétée, les métriques de succès doivent être calculées Valide: Exigences 4.3
Propriété 19: Enregistrement des métriques d'échec
Pour toute erreur survenant, les métriques d'échec et de récupération doivent être enregistrées Valide: Exigences 4.4
Propriété 20: Rapport de performance complet
Pour tout workflow terminé, un rapport de performance complet doit être fourni Valide: Exigences 4.5
Propriété 21: Enregistrement des paramètres de succès
Pour toute action exécutée avec succès, les paramètres de succès doivent être enregistrés pour l'apprentissage Valide: Exigences 5.1
Propriété 22: Renforcement des patterns de matching
Pour toute résolution de cible réussie, les patterns de matching doivent être renforcés Valide: Exigences 5.2
Propriété 23: Apprentissage à partir des récupérations
Pour toute action échouant puis réussissant après récupération, la récupération doit être apprise Valide: Exigences 5.3
Propriété 24: Adaptation des modèles aux évolutions d'interface
Pour toute évolution d'interface détectée, les modèles de reconnaissance doivent être adaptés Valide: Exigences 5.4
Propriété 25: Optimisation basée sur les patterns récurrents
Pour tout pattern récurrent détecté, les stratégies de résolution doivent être optimisées Valide: Exigences 5.5
Propriété 26: Création d'enregistrements d'audit
Pour toute étape de workflow commençant, un enregistrement d'audit détaillé doit être créé Valide: Exigences 6.1
Propriété 27: Enregistrement complet des actions
Pour toute action exécutée, tous les paramètres et résultats doivent être enregistrés Valide: Exigences 6.2
Propriété 28: Documentation du raisonnement
Pour toute décision prise par le système, le raisonnement doit être documenté Valide: Exigences 6.3
Propriété 29: Capture du contexte d'erreur
Pour toute erreur survenant, le contexte complet doit être capturé Valide: Exigences 6.4
Propriété 30: Trace complète pour audit
Pour toute exécution terminée, une trace complète doit être fournie pour l'audit Valide: Exigences 6.5
Propriété 31: Intégration de nouveaux types d'actions
Pour tout nouveau type d'action défini, il doit pouvoir être intégré sans modification du pipeline Valide: Exigences 7.1
Propriété 32: Support des stratégies personnalisées
Pour toute stratégie de résolution personnalisée, elle doit être supportée via des plugins Valide: Exigences 7.2
Propriété 33: Définition de post-conditions personnalisées
Pour toute post-condition spécifique requise, elle doit pouvoir être définie Valide: Exigences 7.3
Propriété 34: Ajout de métriques personnalisées
Pour toute métrique personnalisée nécessaire, elle doit pouvoir être ajoutée Valide: Exigences 7.4
Propriété 35: Réutilisation des analyses d'interface
Pour toute résolution de cible multiple nécessaire, les analyses d'interface doivent être réutilisées Valide: Exigences 8.2
Propriété 36: Optimisation par cache des actions similaires
Pour toute action similaire exécutée, l'optimisation par cache doit être utilisée Valide: Exigences 8.3
Propriété 37: Priorisation des zones d'intérêt
Pour toute interface complexe, les zones d'intérêt doivent être priorisées Valide: Exigences 8.4
Propriété 38: Adaptation aux ressources limitées
Pour toute situation de ressources limitées, la stratégie d'exécution doit être adaptée Valide: Exigences 8.5
Gestion d'Erreurs
Stratégies de Récupération Spécialisées
- SpatialFallbackStrategy : Utilise des critères spatiaux alternatifs
- SemanticVariantStrategy : Essaie des variantes sémantiques
- UIRefreshStrategy : Rafraîchit l'analyse de l'interface
- DynamicAdaptationStrategy : S'adapte aux changements d'interface
- RelearningStrategy : Réapprend les patterns de l'interface
Escalade Intelligente
class IntelligentEscalation:
def escalate_with_context(self, error: Exception,
recovery_attempts: List[RecoveryAttempt],
context: ExecutionContext) -> EscalationResult:
"""
Escalade intelligente avec contexte complet
Informations d'escalade:
1. Erreur originale avec stack trace
2. Toutes les tentatives de récupération
3. Contexte d'exécution complet
4. État de l'interface au moment de l'erreur
5. Recommandations pour la résolution manuelle
"""
Stratégie de Test
Tests Unitaires
- Test d'intégration ExecutionEngine avec tous les composants
- Test de gestion du contexte d'exécution
- Test des stratégies de récupération d'erreurs
- Test des optimisations de performance
- Test de l'apprentissage intégré
- Test de la traçabilité et audit
Tests de Propriétés
Utilisation du framework Hypothesis avec 100+ itérations par propriété pour toutes les 38 propriétés définies.
Tests d'Intégration
- Exécution de workflows complets de bout en bout
- Test de performance avec interfaces complexes
- Test de robustesse avec erreurs simulées
- Test d'apprentissage avec évolution d'interface
- Test de charge avec exécution parallèle
Validation de Non-Régression
Principe Critique : L'intégration doit préserver toutes les fonctionnalités existantes de WorkflowPipeline et ActionExecutor tout en ajoutant les nouvelles capacités.
class IntegrationRegressionValidator:
def validate_no_regression(self, before_integration: SystemState,
after_integration: SystemState) -> ValidationResult:
"""
Valide qu'aucune régression n'a été introduite par l'intégration
Vérifications:
1. Toutes les fonctionnalités WorkflowPipeline préservées
2. Toutes les fonctionnalités ActionExecutor préservées
3. Performances maintenues ou améliorées
4. Contrats d'API inchangés
5. Tests existants continuent de passer
"""