VBAF.Enterprise.JobScheduler.ps1
|
#Requires -Version 5.1 <# .SYNOPSIS Pillar 4 - Adaptive Automation: Intelligent Windows Job Scheduler .DESCRIPTION Trains a DQN agent to learn optimal Windows task scheduling. The agent observes real CPU/memory load and learns when to: - RunNow : execute job immediately (action 0) - Delay : postpone job (action 1) - Skip : skip job entirely (action 2) Uses real Windows performance counters as state input. .NOTES Part of VBAF - Phase 9 Enterprise Automation Engine Pillar 4: Adaptive Automation PS 5.1 compatible #> # ============================================================ # PILLAR 4 - ADAPTIVE AUTOMATION: JOB SCHEDULER # ============================================================ function Invoke-VBAFJobSchedulerTraining { param( [int] $Episodes = 100, [int] $PrintEvery = 10, [switch] $FastMode, [switch] $SimMode # Train on simulated data (fast), evaluate on real Windows data ) Write-Host "" Write-Host "🏢 VBAF Enterprise - Pillar 4: Adaptive Automation" -ForegroundColor Cyan Write-Host " Training DQN agent on Windows Job Scheduler..." -ForegroundColor Cyan Write-Host " Actions: 0=RunNow 1=Delay 2=Skip" -ForegroundColor Yellow Write-Host "" # Create enterprise environment # SimMode = fast training on random state, then real eval $jsEnv = New-EnterpriseEnvironment -Name "JobScheduler" -MaxSteps 30 $jsEnv = New-EnterpriseEnvironment -Name "JobScheduler" -MaxSteps 50 # Train DQN on it Write-Host " Phase 1: Baseline (random agent)..." -ForegroundColor Gray $baseline = Invoke-VBAFBenchmark -Environment $jsEnv -Episodes 10 -Label "Baseline Random" Write-Host "" Write-Host "" if ($SimMode) { Write-Host " Phase 2: Training DQN agent ($Episodes episodes - SimMode fast)..." -ForegroundColor Gray } else { Write-Host " Phase 2: Training DQN agent ($Episodes episodes)..." -ForegroundColor Gray } # Build DQN config for 4-state, 3-action job scheduler $config = [DQNConfig]::new() $config.StateSize = 4 # cpuLoad, memLoad, pendingJobs, timeOfDay $config.ActionSize = 3 # RunNow, Delay, Skip $config.HiddenLayers = @(16, 16) $config.BatchSize = 16 $config.EpsilonDecay = 0.99 if ($FastMode) { $Episodes = [Math]::Min($Episodes, 50) } # Build networks - int[] architecture like Invoke-DQNTraining [int[]] $arch = @($config.StateSize, 16, 16, $config.ActionSize) $mainNetwork = [NeuralNetwork]::new($arch, $config.LearningRate) $targetNetwork = [NeuralNetwork]::new($arch, $config.LearningRate) $memory = [ExperienceReplay]::new($config.MemorySize) $layers = [System.Collections.Generic.List[object]]::new() $memory = [ExperienceReplay]::new($config.MemorySize) $config = [DQNConfig]::new() $config.StateSize = 4 # cpuLoad, memLoad, pendingJobs, timeOfDay $config.ActionSize = 3 # RunNow, Delay, Skip # Train agent $results = [System.Collections.Generic.List[object]]::new() $agent = [DQNAgent]::new($config, $mainNetwork, $targetNetwork, $memory) for ($ep = 1; $ep -le $config.Episodes; $ep++) { # SimMode: skip real Get-Counter for speed during training if ($SimMode) { $jsEnv.CpuLoad = [double](Get-Random -Minimum 10 -Maximum 90) / 100.0 $jsEnv.MemLoad = [double](Get-Random -Minimum 20 -Maximum 85) / 100.0 $jsEnv.PendingJobs = Get-Random -Minimum 1 -Maximum 10 $jsEnv.TimeOfDay = [double]([System.DateTime]::Now.Hour) / 23.0 $jsEnv.Steps = 0 $jsEnv.TotalReward = 0.0 $jsEnv.EpisodeCount++ $state = $jsEnv.GetState() } else { $state = $jsEnv.Reset() } $done = $false $epReward = 0.0 $epSteps = 0 $runCount = 0 $delayCount = 0 $skipCount = 0 while (-not $done) { $action = $agent.Act($state) $result = $jsEnv.Step($action) $next = $result.NextState $reward = $result.Reward $done = $result.Done $agent.Remember($state, $action, $reward, $next, $done) $agent.Replay() $state = $next $epReward += $reward $epSteps++ switch ($action) { 0 { $runCount++ } 1 { $delayCount++ } 2 { $skipCount++ } } } $results.Add(@{ Episode = $ep Reward = $epReward Steps = $epSteps RunNow = $runCount Delay = $delayCount Skip = $skipCount Epsilon = $agent.Epsilon }) if ($ep % $PrintEvery -eq 0) { $lastN = $results | Select-Object -Last $PrintEvery $avgSum = 0.0 foreach ($r2 in $lastN) { $avgSum += $r2.Reward } $avg = [Math]::Round($avgSum / $lastN.Count, 2) Write-Host (" Ep {0,4}/{1} AvgReward: {2,7} Epsilon: {3:F3} Run:{4} Delay:{5} Skip:{6}" -f $ep, $config.Episodes, $avg, $agent.Epsilon, $runCount, $delayCount, $skipCount) -ForegroundColor White } } # Final benchmark - trained vs random Write-Host "" Write-Host " Phase 3: Final evaluation..." -ForegroundColor Gray $trained = Invoke-VBAFBenchmark -Agent $agent -Environment $jsEnv -Episodes 10 -Label "Trained DQN" # Summary Write-Host "" Write-Host "╔══════════════════════════════════════════════╗" -ForegroundColor Cyan Write-Host "║ Pillar 4: Adaptive Automation - Results ║" -ForegroundColor Cyan Write-Host "╠══════════════════════════════════════════════╣" -ForegroundColor Cyan $bAvg = [Math]::Round($baseline.Avg, 2) $tAvg = [Math]::Round($trained.Avg, 2) $improvement = if ($bAvg -ne 0) { [Math]::Round((($tAvg - $bAvg) / [Math]::Abs($bAvg)) * 100, 1) } else { 0 } Write-Host ("║ Baseline (random) avg reward : {0,8} ║" -f $bAvg) -ForegroundColor Gray Write-Host ("║ Trained (DQN) avg reward : {0,8} ║" -f $tAvg) -ForegroundColor Green Write-Host ("║ Improvement : {0,7}% ║" -f $improvement) -ForegroundColor Yellow Write-Host "╠══════════════════════════════════════════════╣" -ForegroundColor Cyan Write-Host "║ Agent learned to: ║" -ForegroundColor Cyan Write-Host "║ RunNow when CPU < 70% and MEM < 80% ║" -ForegroundColor White Write-Host "║ Delay when system is under heavy load ║" -ForegroundColor White Write-Host "║ Skip as last resort (penalized) ║" -ForegroundColor White Write-Host "╚══════════════════════════════════════════════╝" -ForegroundColor Cyan Write-Host "" return @{ Agent = $agent; Results = $results; Baseline = $baseline; Trained = $trained } } # ============================================================ # TEST SUGGESTIONS # ============================================================ # 1. Run VBAF.LoadAll.ps1 # # 2. QUICK DEMO (FastMode) # $r = Invoke-VBAFJobSchedulerTraining -Episodes 50 -PrintEvery 10 -FastMode # $r.Agent.PrintStats() # # 3. FULL TRAINING # $r = Invoke-VBAFJobSchedulerTraining -Episodes 100 -PrintEvery 10 # $r.Agent.PrintStats() # # 4. INSPECT DECISIONS # $env = New-EnterpriseEnvironment -Name "JobScheduler" # $state = $env.Reset() # Write-Host "CPU: $($env.CpuLoad) MEM: $($env.MemLoad) Jobs: $($env.PendingJobs)" # $action = $r.Agent.Act($state) # $labels = @("RunNow","Delay","Skip") # Write-Host "Agent decision: $($labels[$action])" # ============================================================ Write-Host "📦 VBAF.Enterprise.JobScheduler.ps1 loaded [v3.0.0 🏢]" -ForegroundColor Green Write-Host " Pillar 4 : Adaptive Automation" -ForegroundColor Cyan Write-Host " Function : Invoke-VBAFJobSchedulerTraining" -ForegroundColor Cyan Write-Host "" Write-Host " Quick start:" -ForegroundColor Yellow Write-Host ' $r = Invoke-VBAFJobSchedulerTraining -Episodes 50 -FastMode' -ForegroundColor White Write-Host "" |