param( [ValidateScript({ $_ -ge 100 -and $_ % 100 -eq 0 })] [int]$Rounds = 3000 ) $ErrorActionPreference = "Stop" $utf8Encoding = New-Object System.Text.UTF8Encoding($false) [Console]::OutputEncoding = $utf8Encoding $OutputEncoding = $utf8Encoding $mutex = New-Object System.Threading.Mutex($false, "Local\AiChat-Conversation-Adversarial") $ownsMutex = $false try { try { $ownsMutex = $mutex.WaitOne(0) } catch [System.Threading.AbandonedMutexException] { $ownsMutex = $true } if (!$ownsMutex) { Write-Host ">> Another conversation adversarial run is active; skipping overlap." -ForegroundColor Yellow exit 0 } $root = Split-Path -Parent $PSScriptRoot $logRoot = Join-Path $root "logs\conversation" if (!(Test-Path $logRoot)) { New-Item -ItemType Directory -Path $logRoot -Force | Out-Null } $timestamp = Get-Date -Format "yyyyMMdd-HHmmss" $logFile = Join-Path $logRoot "conversation-adversarial-$timestamp.log" $summaryFile = Join-Path $logRoot "conversation-adversarial-$timestamp.summary.json" $testScript = Join-Path $root "backend\tests\conversation_adversarial_regression.php" Write-Host ">> Running $Rounds adversarial conversation rounds" -ForegroundColor Cyan & php $testScript $Rounds $summaryFile 2>&1 | ForEach-Object { $line = [string]$_ Write-Host $line Add-Content -Path $logFile -Value $line -Encoding UTF8 } $exitCode = $LASTEXITCODE if ($exitCode -ne 0) { Write-Error "Conversation adversarial test failed with exit code $exitCode. Log: $logFile" exit $exitCode } Write-Host ">> Conversation adversarial test passed. Log: $logFile" -ForegroundColor Green } finally { if ($ownsMutex) { $mutex.ReleaseMutex() } $mutex.Dispose() }