Advanced Illustration System
Brobot's advanced illustration system provides intelligent, context-aware visual documentation of automation actions with performance optimization and quality-based filtering.
Overview
The enhanced illustration system includes:
- Context-aware illustration decisions based on action history and system state
- Performance optimization with adaptive sampling and batching
- Quality-based filtering to focus on meaningful visualizations
- Granular configuration for different environments and use cases
- Resource management to prevent system overload
Configuration System
Basic Configuration
@Configuration
public class IllustrationConfig {
@Bean
public IllustrationConfig illustrationConfig() {
return IllustrationConfig.builder()
.globalEnabled(true)
.actionEnabled(ActionType.FIND, true)
.actionEnabled(ActionType.CLICK, true)
.actionEnabled(ActionType.MOVE, false) // Disable noisy move illustrations
.qualityThreshold(0.75) // Only illustrate high-quality matches
.maxIllustrationsPerMinute(30) // Rate limiting
.build();
}
}
Context-Based Filtering
@Test
public void configureContextFilters() {
IllustrationConfig config = IllustrationConfig.builder()
.globalEnabled(true)
// Only illustrate failures for debugging
.contextFilter("failures_only", context ->
context.getLastActionResult() != null &&
!context.getLastActionResult().isSuccess())
// Only illustrate first occurrence of each action type
.contextFilter("first_occurrence", context ->
context.isFirstExecution())
// Only illustrate during retry attempts
.contextFilter("retries_only", context ->
context.isRetryAttempt())
.build();
illustrationController.setConfig(config);
}
Adaptive Sampling
@Configuration
public class PerformanceOptimizedIllustrations {
@Bean
public IllustrationConfig performanceConfig() {
return IllustrationConfig.builder()
.globalEnabled(true)
.adaptiveSampling(true) // Enable intelligent sampling
// High-frequency actions get reduced sampling
.samplingRate(ActionType.FIND, 1.0) // Always illustrate find
.samplingRate(ActionType.MOVE, 0.1) // Sample 10% of moves
.samplingRate(ActionType.CLICK, 0.5) // Sample 50% of clicks
// Performance-based batching
.batchConfig(BatchConfig.builder()
.maxBatchSize(20)
.flushInterval(Duration.ofSeconds(10))
.flushOnStateTransition(true)
.maxMemoryUsageMB(50)
.build())
.build();
}
}
Quality-Based Filtering
Basic Quality Metrics
IllustrationConfig qualityFocusedConfig = IllustrationConfig.builder()
.qualityThreshold(0.8) // Only illustrate matches with >80% quality
.qualityMetrics(QualityMetrics.builder()
.minSimilarity(0.75) // Minimum image similarity
.minConfidence(0.6) // Minimum match confidence
.useRegionSize(true) // Consider region size in quality
.useExecutionTime(false) // Don't factor in timing
.build())
.build();
Custom Quality Calculation
IllustrationConfig customQualityConfig = IllustrationConfig.builder()
.qualityThreshold(0.7)
.qualityMetrics(QualityMetrics.builder()
.customQualityCalculator(context -> {
ActionResult result = context.getLastActionResult();
if (result == null || result.getMatchList().isEmpty()) {
return 0.0;
}
// Custom quality calculation
double avgSimilarity = result.getMatchList().stream()
.mapToDouble(match -> match.getScore())
.average().orElse(0.0);
// Boost quality for first executions
if (context.isFirstExecution()) {
avgSimilarity *= 1.2;
}
// Reduce quality for frequent actions
if (context.getRecentIllustrationCount() > 10) {
avgSimilarity *= 0.8;
}
return Math.min(1.0, avgSimilarity);
})
.build())
.build();
Performance Optimization
Smart Sampling Strategies
@Service
public class CustomIllustrationStrategy {
@Autowired
private IllustrationPerformanceOptimizer optimizer;
public void configureAdaptiveSampling() {
IllustrationConfig config = IllustrationConfig.builder()
.adaptiveSampling(true)
.samplingRate(ActionType.FIND, 1.0)
.contextFilter("performance_aware", context -> {
// Skip during high system load
if (context.getSystemMetrics() != null &&
context.getSystemMetrics().isHighLoad()) {
return context.getPriority() == IllustrationContext.Priority.CRITICAL;
}
// Reduce frequency for repeated actions
if (context.getConsecutiveFailures() > 0) {
return true; // Always illustrate during failures
}
// Sample based on recent success rate
return context.getRecentSuccessRate() < 0.9; // Illustrate when success rate drops
})
.build();
optimizer.setConfig(config);
}
}
Batching for Performance
@Test
public void testBatchedIllustrations() {
IllustrationConfig config = IllustrationConfig.builder()
.batchConfig(BatchConfig.builder()
.maxBatchSize(50) // Batch up to 50 illustrations
.flushInterval(Duration.ofSeconds(30)) // Flush every 30 seconds
.flushOnStateTransition(true) // Flush when states change
.maxMemoryUsageMB(100) // Memory limit for batching
.build())
.contextFilter("batch_eligible", context -> {
// Only batch low-priority, frequent actions
return context.getPriority() == IllustrationContext.Priority.LOW &&
context.getCurrentAction() == ActionType.MOVE;
})
.build();
illustrationController.setConfig(config);
// Execute many actions - some will be batched for efficiency
for (int i = 0; i < 100; i++) {
actions.move(randomLocation());
}
// Verify performance optimization worked
PerformanceMetrics.MetricsSnapshot metrics =
illustrationPerformanceOptimizer.getPerformanceMetrics();
assertTrue("Some illustrations should be batched",
metrics.getIllustrationsBatched() > 0);
assertTrue("Skip rate should be reasonable",
metrics.getSkipRate() < 0.8);
}
State-Aware Illustrations
Priority-Based Illustration
IllustrationConfig stateAwareConfig = IllustrationConfig.builder()
// Always illustrate critical states
.alwaysIllustrateState("ERROR_STATE")
.alwaysIllustrateState("LOGIN_FAILURE")
.alwaysIllustrateState("PAYMENT_CONFIRMATION")
// Never illustrate noisy intermediate states
.neverIllustrateAction(ActionType.MOVE)
.contextFilter("state_priority", context -> {
// High priority for error conditions
if (context.hasActiveState("ERROR_STATE", "WARNING_STATE")) {
return true;
}
// Medium priority for authentication flows
if (context.hasActiveState("LOGIN_STATE", "AUTHENTICATION")) {
return context.getConsecutiveFailures() > 0; // Only on failures
}
// Low priority for routine operations
return context.getRecentSuccessRate() < 0.95;
})
.build();