"; } flush(); } function updateProgress($processed, $total) { try { $db = Database::getInstance(); // Only update the most basic columns $updateQuery = "UPDATE optimization_analysis_state SET processed_combinations = ? WHERE id = 1"; $stmt = $db->prepare($updateQuery); if ($stmt) { $stmt->bind_param('i', $processed); $stmt->execute(); } $progress = $total > 0 ? ($processed / $total) * 100 : 0; writeLog("Progress: $processed/$total (" . round($progress, 1) . "%)"); } catch (Exception $e) { writeLog("Progress update failed: " . $e->getMessage(), 'WARN'); } } // Main processing function function processOptimAIzeCombinations() { global $BATCH_SIZE, $MAX_CONSECUTIVE_ERRORS; try { writeLog("=== Minimal OptimAIze Processing Started ==="); writeLog("Configuration: Batch Size=$BATCH_SIZE, Model=" . GPT_MODEL); $db = Database::getInstance(); // Initialize GPT system GptHelper::resetRateLimit(); writeLog("GptHelper initialized"); // Get total count $countResult = $db->query("SELECT COUNT(*) as total FROM panel_directives WHERE llm_checked = 0"); if (!$countResult) { throw new Exception("Failed to count unprocessed combinations"); } $totalCount = $countResult->fetch_assoc()['total']; if ($totalCount == 0) { writeLog("No combinations to process. Analysis complete!"); return true; } writeLog("Total combinations to process: $totalCount"); // Set initial state - only use basic columns $db->query("UPDATE optimization_analysis_state SET is_running = 1, processed_combinations = 0 WHERE id = 1"); $processedCount = 0; $successCount = 0; $errorCount = 0; $consecutiveErrors = 0; $startTime = time(); // Main processing loop while ($processedCount < $totalCount) { // Get next batch $batchQuery = $db->query(" SELECT id, attribute1_name, choice1, attribute2_name, choice2 FROM panel_directives WHERE llm_checked = 0 ORDER BY id ASC LIMIT $BATCH_SIZE "); if (!$batchQuery || $batchQuery->num_rows == 0) { writeLog("No more combinations to process"); break; } $batch = []; while ($row = $batchQuery->fetch_assoc()) { $batch[] = $row; } writeLog("Processing batch of " . count($batch) . " combinations..."); $batchProcessed = 0; $batchErrors = 0; foreach ($batch as $directive) { try { // Analyze the combination $result = GptHelper::analyzeCombination( $directive['attribute1_name'], $directive['choice1'], $directive['attribute2_name'], $directive['choice2'] ); // Update database with result $stmt = $db->prepare(" UPDATE panel_directives SET llm_checked = 1, is_impossible = ?, llm_reasoning = ?, updated_at = NOW() WHERE id = ? "); $isImpossible = $result['is_impossible'] ? 1 : 0; $reasoning = substr($result['reasoning'], 0, 500); $stmt->bind_param('isi', $isImpossible, $reasoning, $directive['id']); if ($stmt->execute()) { $batchProcessed++; $processedCount++; $successCount++; $consecutiveErrors = 0; $resultText = $result['is_impossible'] ? "IMPOSSIBLE" : "POSSIBLE"; $cacheText = isset($result['cached']) && $result['cached'] ? " (cached)" : ""; writeLog("✅ ID {$directive['id']}: $resultText$cacheText"); // Update progress every 10 combinations if ($processedCount % 10 == 0) { updateProgress($processedCount, $totalCount); $elapsed = time() - $startTime; $rate = $elapsed > 0 ? ($processedCount / $elapsed) * 3600 : 0; $eta = $rate > 0 ? (($totalCount - $processedCount) / $rate) : 0; $etaText = $eta > 0 ? gmdate('H:i:s', $eta * 3600) : 'Unknown'; writeLog("Rate: " . round($rate) . "/hour, ETA: $etaText"); } } else { throw new Exception("Database update failed: " . $stmt->error); } } catch (Exception $e) { $batchErrors++; $errorCount++; $consecutiveErrors++; writeLog("❌ Error processing ID {$directive['id']}: " . $e->getMessage(), 'ERROR'); // Handle billing errors specifically if (stripos($e->getMessage(), 'quota') !== false || stripos($e->getMessage(), 'billing') !== false) { writeLog("BILLING ERROR: Need to add credits to OpenAI account", 'ERROR'); throw $e; // Stop processing on billing errors } // Mark as processed with error to avoid infinite retry $errorStmt = $db->prepare(" UPDATE panel_directives SET llm_checked = 1, is_impossible = 0, llm_reasoning = ?, updated_at = NOW() WHERE id = ? "); if ($errorStmt) { $errorReason = "Error: " . substr($e->getMessage(), 0, 200); $errorStmt->bind_param('si', $errorReason, $directive['id']); $errorStmt->execute(); } $processedCount++; // Stop if too many consecutive errors if ($consecutiveErrors >= $MAX_CONSECUTIVE_ERRORS) { throw new Exception("Too many consecutive errors ($consecutiveErrors). Stopping."); } // Wait on rate limit errors if (stripos($e->getMessage(), 'rate limit') !== false) { writeLog("Rate limit hit. Waiting 60 seconds...", 'WARN'); sleep(60); } } } writeLog("Batch complete: $batchProcessed successful, $batchErrors errors"); // Small delay between batches sleep(1); } // Final statistics $totalTime = time() - $startTime; $avgRate = $totalTime > 0 ? ($processedCount / $totalTime) * 3600 : 0; writeLog("=== Processing Complete ==="); writeLog("Total processed: $processedCount"); writeLog("Successful: $successCount"); writeLog("Errors: $errorCount"); writeLog("Success rate: " . round(($successCount / max($processedCount, 1)) * 100, 1) . "%"); writeLog("Total time: " . gmdate('H:i:s', $totalTime)); writeLog("Average rate: " . round($avgRate) . " combinations/hour"); // Mark as completed $db->query("UPDATE optimization_analysis_state SET is_running = 0 WHERE id = 1"); updateProgress($processedCount, $totalCount); return true; } catch (Exception $e) { writeLog("FATAL ERROR: " . $e->getMessage(), 'ERROR'); try { $db = Database::getInstance(); $db->query("UPDATE optimization_analysis_state SET is_running = 0 WHERE id = 1"); } catch (Exception $e2) { writeLog("Could not update state: " . $e2->getMessage(), 'ERROR'); } return false; } } // Execute the processing writeLog("Starting minimal OptimAIze processing..."); echo "
"; echo "

🔄 Processing Status

"; echo "

Mode: Minimal database compatibility

"; echo "

Batch size: $BATCH_SIZE combinations at a time

"; echo "

Model: " . GPT_MODEL . " (cost-effective)

"; echo "

Keep this tab open during processing

"; echo "
"; $result = processOptimAIzeCombinations(); if ($result) { writeLog("Processing completed successfully!"); echo "
"; echo "✅ Processing completed successfully!
"; echo "Check the logs above for detailed statistics and refresh your OptimAIze dashboard."; echo "
"; } else { writeLog("Processing failed with errors."); echo "
"; echo "❌ Processing failed.
"; echo "Common issues:
"; echo "• Billing: Add more credits to your OpenAI account
"; echo "• Rate limits: Will auto-retry
"; echo "• Network issues: Check internet connection
"; echo "
"; } ?>