Spaces:
Running
Running
// import { GoogleGenerativeAI } from 'https://esm.sh/@google/generative-ai'; // REMOVED SDK IMPORT | |
import { marked } from 'https://esm.sh/marked'; | |
import DOMPurify from 'https://esm.sh/dompurify'; | |
const sendBtn = document.getElementById('send-btn'); | |
const messageInput = document.getElementById('message-input'); | |
const typingIndicator = document.getElementById('typing-indicator'); | |
const messagesContainer = document.getElementById('messages-container'); | |
const welcomeScreen = document.getElementById('welcome-screen'); | |
const chatContainer = document.getElementById('chat-container'); | |
const initErrorMsgElement = document.getElementById('init-error-message'); | |
const sdkErrorOverlay = document.getElementById('sdk-error-overlay'); // Keep for displaying errors, even if not SDK specific | |
const reloadButton = document.getElementById('reload-button'); | |
const modeButtons = { | |
simple: document.getElementById('btn-simple') | |
}; | |
// REMOVED SDK specific variables | |
// let genAI; | |
// let model; | |
let isInitialized = false; // Still useful to track if API is reachable | |
let currentMode = 'default'; // Default: Enhanced Synthesis (Code/Math Focus) | |
const API_KEY = "AIzaSyBCURZf72ZWwMN2SHZ7XCQoNgExV4WMX8E"; // β’οΈβ’οΈβ’οΈ WARNING: INSECURE! LOCAL TESTING ONLY! | |
const MODEL_NAME = 'gemini-2.0-flash-thinking-exp-1219'; // β οΈ Experimental Model | |
// --- Construct the REST API endpoint --- | |
// Note: v1beta might be needed depending on the model/features. Adjust if necessary. | |
const API_ENDPOINT_BASE = `https://generativelanguage.googleapis.com/v1beta/models/${MODEL_NAME}`; | |
// --- IMPROVED Solver Params --- | |
const solverParams = { | |
// Temperatures (Core) | |
initial_gen_temp_single: 1.0, // Max exploration for G | |
refine_temp: 1.0, // Max exploration for R | |
verify_temp: 0.1, // Max precision/determinism for C | |
synthesis_temp: 0.85, // **Corrected**: Balanced synthesis for S (as per description) | |
// Sampling | |
topP: 0.98, // Wide nucleus for diversity | |
topK: 80, // Allow reasonably diverse tokens | |
// Retry logic | |
max_retries: 3, | |
// Token Limits (Adjust based on model & typical use cases) | |
max_initial_tokens: 100000, | |
max_critique_tokens: 100000, | |
max_refine_tokens: 100000, | |
max_synthesis_tokens: 122880, | |
max_reasoning_tokens: 100000, // Kept for the Analysis section prompt within Synthesis | |
// --- PPO-like Prompting Control Parameters --- | |
// For Default Mode (Code/Math Focus - MAXIMIZED) | |
depth_focus_max: 0.95, // Emphasize extreme depth | |
creativity_focus_max: 0.90, // Emphasize high creativity/novelty | |
analytical_rigor_max: 0.98, // Demand extreme rigor/correctness | |
alternative_exploration_max: 0.95, // Demand wide exploration of alternatives | |
efficiency_focus_max: 0.90, // Explicit focus on optimal efficiency | |
// For Simple Mode (Generic Focus - MODERATE) | |
depth_focus_simple: 0.65, // Encourage moderate depth/insight | |
creativity_focus_simple: 0.70, // Encourage considering alternatives/angles | |
analytical_rigor_simple: 0.75, // Encourage reasonable accuracy/clarity | |
alternative_exploration_simple: 0.60, // Encourage awareness of options | |
efficiency_focus_simple: 0.50, // Mild awareness of efficiency | |
}; | |
// --- Helper Functions (Error Handling, Init, etc. - Mostly unchanged) --- | |
function showFatalError(title, message) { | |
console.error(`π΄ FATAL ERROR: ${title} - ${message}`); | |
if (messageInput) { | |
messageInput.disabled = true; | |
messageInput.placeholder = "Initialization Failed"; | |
messageInput.dataset.initFailed = 'true'; | |
} | |
if (sendBtn) sendBtn.disabled = true; | |
if (typingIndicator) typingIndicator.classList.add('hidden'); | |
if (initErrorMsgElement) initErrorMsgElement.textContent = `Critical Error: ${title}`; | |
if (sdkErrorOverlay) { | |
const errorBox = sdkErrorOverlay.querySelector('#sdk-error-box'); | |
if(errorBox) { | |
errorBox.querySelector('h3').textContent = title; | |
errorBox.querySelectorAll('p:not(:first-child), ul, ol').forEach(el => el.remove()); | |
const detailParagraph = document.createElement('p'); | |
detailParagraph.textContent = `${message}. Check console (F12) for details.`; | |
errorBox.insertBefore(detailParagraph, errorBox.querySelector('#reload-button')); | |
} | |
sdkErrorOverlay.classList.add('visible'); | |
} | |
} | |
// Modified to handle fetch errors and API specific JSON errors | |
async function handleInitializationError(error, context = "initializeAI") { | |
console.error(`π΄ API Error (${context}):`, error); | |
isInitialized = false; | |
// model = null; // No longer using model variable | |
let userFriendlyTitle = "AI Initialization Failed"; | |
let userFriendlyMessage = "Could not set up the AI session via direct API call."; | |
const errorStatus = error?.response?.status || error?.status; // Try to get status code | |
// Check API Key first | |
if (API_KEY === "YOUR_API_KEY_HERE" || !API_KEY || API_KEY.length < 30) { | |
userFriendlyTitle = "API Key Missing"; | |
userFriendlyMessage = "Please replace 'YOUR_API_KEY_HERE' or provide a valid API key in the code (for local testing ONLY)."; | |
} | |
// Check specific error messages or status codes | |
else if (error.message && (error.message.includes("API key not valid") || error.message.includes("provide an API key") || errorStatus === 403 || errorStatus === 401)) { | |
userFriendlyTitle = "API Key Error"; | |
userFriendlyMessage = `Invalid API Key provided or permission denied (${errorStatus}). Check the key format and ensure it's active and enabled for the Generative Language API.`; | |
} else if (errorStatus === 429 || error.message?.includes("quota")) { | |
userFriendlyTitle = "Quota Exceeded"; | |
userFriendlyMessage = "API usage limit reached (429)."; | |
} else if (errorStatus === 404 || error.message?.includes("model") || error.message?.includes("not found")) { | |
userFriendlyTitle = "Model Not Found/Allowed"; | |
userFriendlyMessage = `Error: Model '${MODEL_NAME}' not found at endpoint or unavailable for this API key (${errorStatus}). Try 'gemini-1.5-flash-latest' or check API endpoint/key permissions.`; | |
} else if (error.message?.includes("User location is not supported")) { // This message might come in the response body | |
userFriendlyTitle = "Location Not Supported"; | |
userFriendlyMessage = `Error: User location not supported for model '${MODEL_NAME}'.`; | |
} else if (errorStatus === 400 || error.message?.includes("Bad Request")) { | |
userFriendlyTitle = "Bad Request (400)"; | |
userFriendlyMessage = `Error with request format or parameters for ${MODEL_NAME}. ${error.message || 'Check API documentation.'}`; | |
} else if (errorStatus >= 500) { | |
userFriendlyTitle = `Server Error (${errorStatus})`; | |
userFriendlyMessage = "AI service internal issue."; | |
} else if (error instanceof TypeError && error.message.includes('fetch')) { | |
userFriendlyTitle = "Network Error"; | |
userFriendlyMessage = `Failed to fetch from the API endpoint. Check network connection and API endpoint URL. (${error.message})`; | |
} | |
// Try to extract details from a JSON error response if available | |
else if (error.responseBody && error.responseBody.error && error.responseBody.error.message) { | |
userFriendlyMessage = `API Error (${errorStatus || 'Unknown Status'}): ${error.responseBody.error.message}`; | |
if(error.responseBody.error.details) console.error("API Error Details:", error.responseBody.error.details); | |
} | |
else { // Generic fallback | |
userFriendlyMessage = `Initialization Error: ${error.message || 'Unknown error occurred during API interaction.'}`; | |
} | |
showFatalError(userFriendlyTitle, userFriendlyMessage); | |
if (messageInput) messageInput.dataset.initFailed = 'true'; | |
} | |
// Modified to use fetch for the initial check | |
async function initializeAI() { | |
console.log(`β³ Initializing AI via REST API (Model: ${MODEL_NAME})...`); | |
if (!API_KEY || API_KEY === "YOUR_API_KEY_HERE" || API_KEY.length < 30) { | |
// Use a more specific error object for clarity | |
handleInitializationError(new Error("API key is missing, placeholder, or invalid format."), "initializeAI_PreCheck"); | |
return; | |
} | |
initErrorMsgElement.textContent = ""; | |
sdkErrorOverlay.classList.remove('visible'); | |
isInitialized = false; // Reset status | |
const testPrompt = "test prompt"; | |
const apiUrl = `${API_ENDPOINT_BASE}:generateContent?key=${API_KEY}`; | |
const requestBody = { | |
// Use minimal generation config for testing | |
contents: [{ parts: [{ text: testPrompt }] }], | |
generationConfig: { | |
temperature: 0.1, | |
maxOutputTokens: 5 | |
} | |
}; | |
try { | |
console.log(`β³ Performing API access test via fetch to: ${API_ENDPOINT_BASE}...`); | |
const response = await fetch(apiUrl, { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
body: JSON.stringify(requestBody), | |
}); | |
console.log(` API Test Response Status: ${response.status}`); | |
if (!response.ok) { | |
let errorBody = null; | |
try { | |
errorBody = await response.json(); // Try to get detailed error | |
console.error(" API Test Error Response Body:", errorBody); | |
} catch (parseError) { | |
console.warn(" Could not parse error response body as JSON."); | |
errorBody = { error: { message: await response.text() || `HTTP Error ${response.status}` }}; | |
} | |
// Create a custom error object to pass details | |
const apiError = new Error(`API test request failed with status ${response.status}`); | |
apiError.status = response.status; | |
apiError.responseBody = errorBody; // Attach parsed body | |
throw apiError; | |
} | |
// Optional: Check response content minimally | |
const data = await response.json(); | |
if (!data.candidates || data.candidates.length === 0) { | |
console.warn(" API Test response OK, but no candidates returned.", data); | |
// Decide if this is an error state for your use case | |
// throw new Error("API test successful but response format unexpected (no candidates)."); | |
} | |
console.log("β API access test successful."); | |
isInitialized = true; | |
console.log(`π AI Initialized Successfully via REST API with model: ${MODEL_NAME}`); | |
if (messageInput) { | |
messageInput.disabled = false; | |
messageInput.placeholder = "Enter prompt (Default: Enhanced Synthesis - Code/Math Focus)..."; | |
delete messageInput.dataset.initFailed; | |
} | |
if (sendBtn) sendBtn.disabled = false; | |
} catch (error) { | |
handleInitializationError(error, "initializeAI_Fetch"); | |
} | |
} | |
// --- Core function modified to use fetch --- | |
async function generateWithRetry(prompt, temp, maxOutputTokens, retries = solverParams.max_retries) { | |
// No longer need model check, rely on isInitialized | |
if (!isInitialized) { console.error("π΄ generateWithRetry: API not initialized successfully."); return "(Error: API not ready)"; } | |
let lastException = null; | |
const apiUrl = `${API_ENDPOINT_BASE}:generateContent?key=${API_KEY}`; | |
const requestBody = { | |
contents: [{ parts: [{ text: prompt }] }], | |
generationConfig: { | |
temperature: temp, | |
topP: solverParams.topP, | |
topK: solverParams.topK, | |
maxOutputTokens: maxOutputTokens // Correctly placed within generationConfig for REST API | |
} | |
// safetySettings: [] // Optional: Add safety settings if needed | |
}; | |
for (let attempt = 1; attempt <= retries; attempt++) { | |
try { | |
console.log(` β³ API Call attempt ${attempt}/${retries} (Temp: ${temp.toFixed(2)}, MaxTokens: ${maxOutputTokens}, topP: ${requestBody.generationConfig.topP}, topK: ${requestBody.generationConfig.topK})`); | |
const response = await fetch(apiUrl, { | |
method: 'POST', | |
headers: { 'Content-Type': 'application/json' }, | |
body: JSON.stringify(requestBody) | |
}); | |
const responseData = await response.json(); // Assume response is JSON, handle parsing errors below | |
if (!response.ok) { | |
console.warn(` β οΈ API Call Failed (Attempt ${attempt}) - Status: ${response.status}`); | |
console.warn(" Error Response Body:", responseData); | |
// Create an error object similar to how SDK might behave | |
const apiError = new Error(responseData?.error?.message || `API request failed with status ${response.status}`); | |
apiError.status = response.status; | |
apiError.details = responseData?.error?.details; // Add details if available | |
apiError.responseBody = responseData; // Keep full body for inspection | |
throw apiError; // Throw to trigger retry/error handling logic | |
} | |
// --- Process Successful Response --- | |
// Check for blocking reasons | |
const blockReason = responseData?.promptFeedback?.blockReason; | |
if (blockReason) { | |
console.warn(` π« Generation blocked (Attempt ${attempt}). Reason: ${blockReason}`); | |
if (blockReason === "SAFETY" || blockReason === "OTHER") { | |
console.warn(` Retrying after SAFETY/OTHER block (attempt ${attempt})...`); | |
await new Promise(resolve => setTimeout(resolve, 500 * attempt)); | |
continue; // Retry on SAFETY/OTHER | |
} else { | |
console.warn(` Stopping retries due to non-recoverable block reason: ${blockReason}`); | |
// Try to get safety ratings info if available | |
const safetyInfo = JSON.stringify(responseData.promptFeedback?.safetyRatings || {}); | |
return `(Error: Blocked by API - Reason: ${blockReason}. Details: ${safetyInfo})`; // Stop on other blocks | |
} | |
} | |
// Extract text - Check structure carefully based on API response | |
let fullText = responseData.candidates?.[0]?.content?.parts?.[0]?.text; | |
const finishReason = responseData.candidates?.[0]?.finishReason || "UNKNOWN"; | |
// REST API might not have validationError in the same place, check finishReason/message | |
// const validationError = responseData?.candidates?.[0]?.content?.parts?.[0]?.validationError; // SDK specific? | |
if (fullText && fullText.trim().length > 0) { // Check if text is not empty | |
console.log(` β Generation success (Attempt ${attempt})`); | |
return fullText; | |
} else { | |
console.warn(` β οΈ Empty or potentially invalid response (Attempt ${attempt}). Finish Reason: ${finishReason}.`); | |
// Handle specific finish reasons | |
if (['MAX_TOKENS', 'RECITATION', 'SAFETY', 'OTHER'].includes(finishReason)) { | |
console.warn(` Potentially non-recoverable finish reason (${finishReason}), stopping retries.`); | |
return `(Error: Generation failed or empty. Finish Reason: ${finishReason})`; | |
} | |
// Handle case where response is empty but finish reason is 'STOP' | |
if (finishReason === "STOP" && (!fullText || fullText.trim().length === 0)) { | |
if (attempt < retries) { | |
console.log(" Empty response with STOP reason, retrying once more..."); | |
await new Promise(resolve => setTimeout(resolve, 500 * attempt)); | |
continue; // Retry once more | |
} else { | |
console.warn(" Empty response with STOP reason after final retry."); | |
return `(Error: Generation resulted in empty response after retries. Finish Reason: STOP)`; | |
} | |
} | |
// Unexpected empty state | |
console.warn(" Unexpected empty response state, breaking retry loop."); | |
break; | |
} | |
// --- Catch Block for fetch/parsing/API errors --- | |
} catch (error) { | |
console.error(` π΄ Generation Error (Attempt ${attempt}/${retries}): ${error.name}: ${error.message}`); | |
lastException = error; | |
// Check for specific error types or messages | |
if (error instanceof SyntaxError) { // JSON parsing failed | |
console.error(" JSON Parsing Error. Response might not be valid JSON."); | |
// Don't retry parsing errors usually | |
return `(Error: Failed to parse API response. Check console for details.)`; | |
} | |
if (error.message?.includes("API key not valid")) { | |
handleInitializationError(new Error("API key not valid during generation."), "generateWithRetry"); | |
return "(Error: Invalid API Key during generation)"; | |
} | |
let waitTime = Math.pow(1.8, attempt) * 1000; | |
// Get status from the custom error object if possible, or directly | |
const status = error.status || error.response?.status; | |
if (status === 429 || error.message?.includes("429")) { | |
waitTime = 5000 + waitTime; console.warn(" Rate limit (429), waiting longer..."); | |
} else if (status === 400 || error.message?.includes("400")) { | |
console.error(" Bad request (400). Check prompt/parameters. Stopping retries for this call."); | |
const detail = error.details || error.message || error.responseBody?.error?.message || "No additional details"; | |
return `(Error: Bad Request (400) - ${detail})`; | |
} else if (status >= 500 || /5\d{2}/.test(String(status)) || error.message?.includes("50")) { | |
console.warn(` Server error (${status || '5xx'}), waiting before retry...`); | |
waitTime += 2000; | |
} else if (error instanceof TypeError && error.message.includes('fetch')) { | |
console.warn(` Network error during fetch, waiting before retry...`); | |
waitTime += 1500; // Wait a bit for network issues | |
} | |
else { | |
console.warn(` Non-retryable or unknown error status (${status || 'Unknown'}), stopping retries for this call.`); | |
return `(Error: Generation failed with status ${status || 'Unknown'} - ${error.message})`; | |
} | |
if (attempt < retries) { | |
console.log(` Waiting ${waitTime.toFixed(0)}ms before retry ${attempt + 1}...`); | |
await new Promise(resolve => setTimeout(resolve, waitTime)); | |
} | |
} | |
} | |
// --- After retries loop --- | |
console.error(` β Generation failed after ${retries} attempts.`); | |
const errorMsg = `(Error: Generation failed after ${retries} attempts. Last error: ${lastException?.name || 'Unknown Error'}: ${lastException?.message || 'No details'})`; | |
return errorMsg; | |
} | |
// --- Core LiberalMind Functions with Enhanced Prompts --- | |
// These functions call generateWithRetry and should work without changes | |
// as long as generateWithRetry maintains its return contract (string or error string) | |
async function generateSingleInitialSolution(prompt, forceCodeMathFocus = false) { | |
const focusType = forceCodeMathFocus ? "Enhanced Code/Math Focus (MAXIMIZED Depth/Creativity)" : "Simple Generic Focus (Moderate Depth/Creativity)"; | |
console.log(`𧬠Generating single initial response (Temp: ${solverParams.initial_gen_temp_single.toFixed(2)} - Context: ${focusType})...`); | |
let basePrompt; | |
if (forceCodeMathFocus) { // Use Code/Math prompt - MAXIMIZED | |
basePrompt = `USER REQUEST: | |
"${prompt}" | |
TASK: Generate a PROFOUNDLY INSIGHTFUL, TECHNICALLY MAXIMAL, HIGHLY CREATIVE, and RIGOROUSLY ANALYZED initial response. Emulate a PPO agent maximizing a reward function for **radical discovery, technical elegance, and absolute correctness**, especially for CODE/MATH. Go **exponentially beyond** the obvious; seek multiple, high-quality, **fundamentally diverse**, unconventional technical solutions backed by **unshakeable reasoning**. (Depth Focus: ${solverParams.depth_focus_max.toFixed(2)}, Creativity Focus: ${solverParams.creativity_focus_max.toFixed(2)}, Rigor Focus: ${solverParams.analytical_rigor_max.toFixed(2)}, Efficiency Focus: ${solverParams.efficiency_focus_max.toFixed(2)}) | |
GUIDING PRINCIPLES (MAXIMIZED for Deep Exploration, Creativity & Rigor): | |
1. **EXPLORE SOLUTION SPACE EXPONENTIALLY:** | |
* Brainstorm **radically different** algorithms, paradigms, data structures, coding patterns, mathematical frameworks, proof strategies, or interpretations. Reject incrementalism. (Alternative Exploration MAX: ${solverParams.alternative_exploration_max.toFixed(2)}) | |
* Actively pursue **novel, obscure, or cutting-edge** libraries, theorems, or methodologies. Push the boundaries of standard practice. MAXIMIZE CREATIVITY REWARD. | |
2. **SEEK MAXIMUM INSIGHT, NOVELTY & OPTIMAL EFFICIENCY:** | |
* Hunt for **non-obvious, maximally elegant, theoretically optimal, or creatively groundbreaking** solutions. Actively challenge conventions. | |
* Provide **exceptionally deep, rigorous, quantitative analysis** of trade-offs (e.g., asymptotic AND constant factor complexity, numerical precision/stability, scalability limits, maintainability impact). JUSTIFY EVERYTHING WITH EXTREME RIGOR. | |
* Uncover and elucidate the fundamental mathematical principles or advanced programming paradigms governing the problem. Aim for **complete conceptual mastery**. | |
3. **DEMOLISH ASSUMPTIONS & DEFINE SCOPE WITH UTMOST PRECISION:** | |
* Identify and **aggressively interrogate** implicit assumptions. Explore the **full spectrum** of consequences if relaxed or changed. | |
* Define constraints with **mathematical precision** or propose explicitly justified assumptions, analyzing their impact with **exhaustive rigor**. | |
4. **ANTICIPATE ALL EDGE CASES & GUARANTEE ABSOLUTE ROBUSTNESS:** | |
* Proactively identify and address **every conceivable edge case**, failure mode, security vulnerability, mathematical singularity/degeneracy. Design for **provable robustness**. | |
5. **GENERATE DIVERSE, FLAWLESS, DEEPLY ANALYZED OPTIONS:** | |
* Generate **multiple, distinct, complete, runnable/provable, and EXHAUSTIVELY analyzed technical options**. | |
* Provide **razor-sharp, critical comparisons** highlighting subtle yet crucial pros, cons, and trade-offs based on deep analysis. | |
6. **ABSOLUTE ACCURACY AND RIGOR ARE NON-NEGOTIABLE:** | |
* Ensure **mathematical/logical/coding perfection**. Code must be flawless, robust, efficient, and demonstrably correct. Math must be formally immaculate, complete, and insightful. | |
OUTPUT FORMATTING (CRITICAL - MAXIMIZE ANALYZED TECHNICAL CONTENT): | |
* **CODE/MATH OUTPUT IS PARAMOUNT:** Prioritize complete, heavily commented, runnable/verifiable code snippets or detailed, formally perfect mathematical derivations/proofs, **accompanied by CONCISE but PROFOUND analysis** of their properties (complexity, stability, limitations, novelty). | |
* **CLEARLY SEPARATE ALTERNATIVES:** Use distinct, well-labeled sections/code blocks for different technical solutions, including **deep comparative analysis**. | |
* **MINIMIZE PROSE:** Keep text ruthlessly concise, focused *only* on essential explanations of the core technical content, setup, or the **deep analysis mandated**. Assume expert audience. NO VERBOSITY. | |
* Structure logically using headings, code blocks (with language hints), and precise math notation (Markdown LaTeX: $...$ or $$...$$). | |
Address the core task with MAXIMUM technical depth, exploring multiple diverse and robust solutions, prioritizing DEEPLY ANALYZED code/formulas, and minimizing all non-essential text. | |
INITIAL DEEP EXPLORATORY RESPONSE (MAX Code/Math Focus, High Analysis, High Creativity):`; | |
} else { // Use General prompt - MODERATE | |
basePrompt = `USER REQUEST: | |
"${prompt}" | |
TASK: Generate a comprehensive, clear, insightful, and well-structured initial response. Aim for accuracy and clarity, covering key aspects. Briefly explore relevant alternative perspectives or approaches where helpful. (Depth Focus: ${solverParams.depth_focus_simple.toFixed(2)}, Creativity Focus: ${solverParams.creativity_focus_simple.toFixed(2)}, Rigor Focus: ${solverParams.analytical_rigor_simple.toFixed(2)}) | |
GUIDING PRINCIPLES (Balanced Quality & Insight): | |
1. **Address the Core Request Clearly:** Directly answer the user's question or fulfill the task with clarity. | |
2. **Structure and Readability:** Organize information logically (headings, lists, paragraphs). Write clearly and concisely. | |
3. **Accuracy and Soundness:** Ensure factual correctness. If providing code or technical details, ensure they are generally sound and well-explained. (Rigor Focus: ${solverParams.analytical_rigor_simple.toFixed(2)}) | |
4. **Reasonable Completeness & Depth:** Cover the main points. Briefly touch upon important considerations, underlying principles, or potential trade-offs to add useful depth. (Depth Focus: ${solverParams.depth_focus_simple.toFixed(2)}) | |
5. **Consider Alternatives (Helpfulness):** Where appropriate, briefly mention or explain alternative viewpoints, methods, or interpretations to provide a more rounded understanding. (Alternative Exploration: ${solverParams.alternative_exploration_simple.toFixed(2)}, Creativity Focus: ${solverParams.creativity_focus_simple.toFixed(2)}) | |
6. **Efficiency Awareness (Minor):** If relevant (e.g., simple algorithms), be mindful of generally efficient approaches. (Efficiency Focus: ${solverParams.efficiency_focus_simple.toFixed(2)}) | |
OUTPUT FORMATTING: | |
* Use appropriate Markdown formatting for readability. | |
* Present code clearly in code blocks with language hints if possible. | |
* Explain technical concepts clearly and accurately. | |
* Structure logically for easy understanding. | |
INITIAL RESPONSE (Balanced Clarity, Accuracy, Moderate Insight):`; | |
} | |
// Use the correct temperature for initial generation | |
let sol = await generateWithRetry( | |
basePrompt, | |
solverParams.initial_gen_temp_single, | |
solverParams.max_initial_tokens | |
); | |
if (sol && !sol.startsWith('(Error:')) { | |
return sol; | |
} else { | |
console.error(` Failed to generate single initial response (${focusType}). Error/Response: ${sol}`); | |
return null; // Return null for easier checking later | |
} | |
} | |
async function getCritique(textToAnalyze, originalPrompt = "", forceCodeMathFocus = false) { | |
const focusType = forceCodeMathFocus ? "Enhanced Code/Math Rigor (MAXIMIZED Depth/Creativity)" : "Simple Generic Focus (Moderate Depth/Creativity)"; | |
console.log(` π Requesting critique (Context: ${focusType}, Temp: ${solverParams.verify_temp.toFixed(2)})...`); | |
let prompt = ''; | |
let temperature = solverParams.verify_temp; // Always low temp for critique | |
let maxTokens = solverParams.max_critique_tokens; | |
if (forceCodeMathFocus) { // Use Code/Math prompt - MAXIMIZED | |
prompt = `YOU ARE AN **ABSOLUTELY UNCOMPROMISING, HYPER-CRITICAL, DEEPLY ANALYTICAL** UNIVERSAL CRITIC specializing in CODE and MATH. Your function is to simulate an **EXTREME REWARD/PENALTY GRADIENT** for a PPO-like process, ruthlessly pushing towards **PERFECTION in correctness, MAXIMAL technical depth, PEAK efficiency, RADICAL creativity, and EXHAUSTIVE exploration of superior alternatives.** Be pathologically demanding about ANY flaw, superficiality, inefficiency, or lack of true insight. (Depth Focus: ${solverParams.depth_focus_max.toFixed(2)}, Creativity Focus: ${solverParams.creativity_focus_max.toFixed(2)}, Rigor Focus: ${solverParams.analytical_rigor_max.toFixed(2)}, Efficiency Focus: ${solverParams.efficiency_focus_max.toFixed(2)}) | |
Evaluate the provided text/output against these **NON-NEGOTIABLE PILLARS**: | |
1. **Correctness, Clarity & Technical Rigor (INFINITE PENALTY for errors):** | |
* **Code:** Find **EVERY SINGLE BUG** (syntax, runtime, logic, concurrency, security). Is it **OPTIMALLY EFFICIENT** (asymptotically AND practically)? Is the style **PERFECT**? Error handling **BULLETPROOF**? Security **IMPREGNABLE**? | |
* **Math:** Verify **EVERY STEP** with **ABSOLUTE FORMAL RIGOR**. Are formulas exact? Derivations/proofs complete, elegant, justified beyond doubt? Notation flawless? Conditions explicit, necessary, sufficient? | |
* Identify **ANY** ambiguity, factual error, logical leap, or imprecise statement. DEMAND PERFECTION. | |
2. **Exploration, Insightfulness, Creativity & Alternatives (MAXIMIZE REWARD for depth/novelty; MAXIMUM PENALTY for superficiality/obviousness):** | |
* **Technical Alternatives (CRITICAL - MAXIMUM PENALTY IF ABSENT/WEAK):** Did it explore **multiple, fundamentally different, non-obvious, provably valid** approaches? Were these alternatives analyzed comparatively with **profound depth and rigor**? If not, **DEMAND specific, creative, theoretically superior alternatives** be investigated, implemented, and rigorously compared. **PUNISH MENTALLY sticking to basic/standard solutions** without overwhelming justification and deep comparative analysis. (Alternative Exploration MAX: ${solverParams.alternative_exploration_max.toFixed(2)}) | |
* **Depth & Insight:** Is the solution **technically profound**, revealing **deep, non-trivial understanding**? Is the analysis **maximally rigorous, quantitative, insightful, and complete**? DEMAND **ORDERS OF MAGNITUDE deeper analysis**, justification, exploration of trade-offs, and discussion of limitations. **REJECT ALL SURFACE-LEVEL EXPLANATIONS INSTANTLY.** | |
* **Creativity & Novelty:** Does the solution demonstrate **significant originality, elegance, or insight far beyond standard textbook methods**? If not, **explicitly DEMAND investigation into more creative, elegant, or state-of-the-art solutions** [Suggest specific directions if possible]. MAXIMIZE REWARD FOR NOVELTY. | |
* **Efficiency (MAXIMUM PENALTY IF SUBOPTIMAL):** Is the solution **THEORETICALLY AND PRACTICALLY OPTIMAL** in terms of time/space complexity? Are constant factors minimized? If not, **DEMAND investigation and implementation of provably superior approaches.** (Efficiency Focus MAX: ${solverParams.efficiency_focus_max.toFixed(2)}) | |
* **Edge Cases & Robustness:** Did it handle **ALL conceivable edge cases** exhaustively and ensure **provable robustness**? Point out *ANY* potential omission or weakness, however obscure. | |
* **Completeness & Practicality:** Is the solution complete, well-documented, easily usable, and practically viable? Are there **missed opportunities for profound simplification, generalization, or far more illustrative examples**? | |
Original User Request (for context): | |
"${originalPrompt || 'N/A'}" | |
TEXT/OUTPUT TO ANALYZE (Current AI 'Policy' Output): | |
--- START --- | |
${textToAnalyze} | |
--- END --- | |
PROVIDE **ONLY** A LIST OF SPECIFIC, ACTIONABLE, **EXTREMELY DEMANDING**, AND **TECHNICALLY PRECISE** REQUIREMENTS FOR IMPROVEMENT (These are the gradients for the next policy update. Maximize their strength and specificity): | |
Correctness/Rigor Issues (Be Precise, Ruthless & Unforgiving): | |
* [Requirement 1: State the exact code bug/math error/logical flaw/imprecision [Location] and demand the precise correction / rigorous proof step / clarification needed for PERFECTION.] | |
* [...] | |
Exploration/Insight/Alternative/Creativity/Efficiency Gaps (CRITICAL - Demand **MASSIVE, DEEP, SPECIFIC** Action): | |
* [Requirement X: **DEMAND IMMEDIATE exploration, implementation, and DEEP comparative analysis of specific alternative non-obvious/creative/superior algorithms/formulas [Name Them Specifically]** because the current one is [grossly inefficient / trivial / suboptimal / lacks fundamental insight / fails under condition Y]. Provide expected analysis criteria (e.g., complexity, stability bounds).] | |
* [Requirement Y: DEMAND **rigorous, quantitative, formal analysis** of [asymptotic time/space complexity / numerical error bounds / convergence proof / theoretical limits] and comparison with [Specific Alternative]'s proven properties.] | |
* [Requirement Z: Identify specific missed edge cases [Describe Them Precisely] or robustness vulnerabilities and require **comprehensive, mathematically/logically provable handling** and demonstration.] | |
* [Requirement A: State that the solution LACKS ANY REAL CREATIVITY/PROFUNDITY and require investigation and implementation of [Specific novel/elegant/theoretically superior method] to achieve a breakthrough.] | |
* [Requirement B: DEMAND **unshakeable justification** for [Specific technical choice] based on rigorous analysis, formal proof, and deep comparison against specified alternatives.] | |
* [Requirement C: Identify superficial/hand-wavy explanations [Location] and demand **complete rewriting with maximum technical depth, precision, and formal rigor**.] | |
* [Requirement D: Identify suboptimal efficiency and DEMAND implementation and analysis of [Specific Superior Algorithm/Data Structure] with proof of improvement.] | |
Format: Requirements MUST be actionable, specific, technically grounded, and **demand the highest possible standard**. Frame requirements as **imperative commands** for improvement. | |
Output Format (Strictly Adhere): | |
REQUIREMENTS FOR IMPROVEMENT (Policy Update Gradient - MAX STRENGTH): | |
[Requirement 1: ...] | |
[Requirement 2: ...] | |
... | |
[Requirement N: ...] | |
If (and **ONLY IF**) the output is technically **PERFECT**, exceptionally insightful, demonstrates **profound and creative exploration of superior alternatives** with **absolute analytical rigor**, AND fully addresses the request at the **deepest possible level**, output **ONLY**: | |
REQUIREMENTS FOR IMPROVEMENT (Policy Update Gradient - MAX STRENGTH): None.`; | |
} else { // Use General prompt - MODERATE | |
prompt = `You are a helpful AI assistant acting as a constructive critic. Evaluate the provided "Text to Analyze" based on its quality, clarity, accuracy, insightfulness, and how well it addresses the likely "Original User Request". Aim for actionable feedback. (Depth Focus: ${solverParams.depth_focus_simple.toFixed(2)}, Creativity Focus: ${solverParams.creativity_focus_simple.toFixed(2)}, Rigor Focus: ${solverParams.analytical_rigor_simple.toFixed(2)}) | |
Original User Request (for context): | |
"${originalPrompt || 'N/A'}" | |
Text to Analyze: | |
--- START --- | |
${textToAnalyze} | |
--- END --- | |
Provide a list of specific, actionable suggestions for improvement. Focus on: | |
1. **Clarity & Structure:** Is the text easy to understand? Is the language precise? Well-organized? Any confusing parts? | |
2. **Accuracy & Soundness:** Any factual errors, misleading statements? Is code logic generally correct and understandable? (Rigor Focus: ${solverParams.analytical_rigor_simple.toFixed(2)}) | |
3. **Completeness & Depth:** Does it adequately cover the main points? Could key concepts be explained with more helpful detail or insight? (Depth Focus: ${solverParams.depth_focus_simple.toFixed(2)}) | |
4. **Insightfulness & Alternatives:** Could the response be more insightful? Does it consider different angles or alternative interpretations/methods where helpful? Could examples be more illustrative? (Creativity Focus: ${solverParams.creativity_focus_simple.toFixed(2)}, Alternative Exploration: ${solverParams.alternative_exploration_simple.toFixed(2)}) | |
5. **Efficiency Awareness (Minor):** If relevant, are the suggested approaches generally efficient? (Efficiency Focus: ${solverParams.efficiency_focus_simple.toFixed(2)}) | |
6. **Formatting:** Is formatting clear and helpful? | |
Output Format (Strictly Adhere): | |
SUGGESTIONS FOR IMPROVEMENT: | |
* [Suggestion 1: Be specific, e.g., "Clarify the explanation of X in the second paragraph for better understanding."] | |
* [Suggestion 2: e.g., "Consider adding a brief example demonstrating Y to enhance insight."] | |
* [Suggestion 3: e.g., "Verify the accuracy of the statement about Z regarding its implications."] | |
* [Suggestion 4: e.g., "Briefly explaining the trade-offs between approach A and B could add helpful depth."] | |
* [Suggestion 5: e.g., "Could you explore the alternative perspective of [Specific Viewpoint]?"] | |
* [...] | |
If the text is already excellent and requires no significant changes, output ONLY: | |
SUGGESTIONS FOR IMPROVEMENT: None.`; | |
} | |
const result = await generateWithRetry(prompt, temperature, maxTokens); | |
// --- Parsing Logic (unchanged, relies on string output) --- | |
if (result && !result.startsWith('(Error:')) { | |
// Standardize markers check for robustness | |
const noneMarkerAgent = "REQUIREMENTS FOR IMPROVEMENT (Policy Update Gradient - MAX STRENGTH): None."; | |
const noneMarkerGeneric = "SUGGESTIONS FOR IMPROVEMENT: None."; | |
const requirementsMarkerAgent = /REQUIREMENTS FOR IMPROVEMENT \(Policy Update Gradient - MAX STRENGTH\):/i; | |
const suggestionsMarkerGeneric = /SUGGESTIONS FOR IMPROVEMENT:/i; | |
if (result.includes(noneMarkerAgent) || result.includes(noneMarkerGeneric)) { | |
console.log(` β Verifier found no significant flaws/gaps (${focusType}).`); | |
return null; // Use null to indicate no critique | |
} else { | |
let requirements = ""; | |
// Prioritize parsing based on focus type, but allow fallback | |
if (forceCodeMathFocus && requirementsMarkerAgent.test(result)) { | |
requirements = result.replace(requirementsMarkerAgent, "").trim(); | |
} else if (!forceCodeMathFocus && suggestionsMarkerGeneric.test(result)) { | |
requirements = result.replace(suggestionsMarkerGeneric, "").trim(); | |
} else { | |
// Fallback: try removing either marker if present | |
const reqMarkerMatch = result.match(requirementsMarkerAgent); | |
const sugMarkerMatch = result.match(suggestionsMarkerGeneric); | |
if (reqMarkerMatch) { | |
requirements = result.substring(reqMarkerMatch.index + reqMarkerMatch[0].length).trim(); | |
console.warn(` β οΈ Critique response parsed using fallback marker (Agent) for focus type '${focusType}'.`); | |
} else if (sugMarkerMatch) { | |
requirements = result.substring(sugMarkerMatch.index + sugMarkerMatch[0].length).trim(); | |
console.warn(` β οΈ Critique response parsed using fallback marker (Generic) for focus type '${focusType}'.`); | |
} else { | |
requirements = result.trim(); // Last resort: use the whole text | |
console.warn(` β οΈ Critique response lacks expected header for focus type '${focusType}', using full text.`); | |
} | |
} | |
if (requirements && requirements.length > 1) { | |
console.log(` π Critique received (${focusType}):\n${requirements.substring(0, 300)}...`); | |
return requirements; | |
} else { | |
console.warn(" β οΈ Verifier responded, but requirements/suggestions list seems empty/invalid after parsing. Treating as no critique.", result); | |
return null; // Return null if parsing fails | |
} | |
} | |
} else { | |
console.error(` β Failed to get critique (${focusType}). Response: ${result}`); | |
// Return the error string directly for checking later | |
return result || "(Error: Critique generation failed with empty response)"; | |
} | |
} | |
async function refineSolution(originalSolution, correctionRequests, originalPrompt = "", forceCodeMathFocus = false) { | |
const focusType = forceCodeMathFocus ? "Enhanced Code/Math Focus (MAXIMIZED Depth/Creativity)" : "Simple Generic Focus (Moderate Depth/Creativity)"; | |
console.log(` π οΈ Refining solution (Context: ${focusType}, Temp: ${solverParams.refine_temp.toFixed(2)})...`); | |
let prompt; | |
if (forceCodeMathFocus) { // Use Code/Math prompt - MAXIMIZED | |
prompt = `TASK: Execute a **TRANSFORMATIVE REVISION** of the 'Original Text/Output' (current policy) based on the **EXTREME** 'Requirements for Improvement' (policy update gradient). Generate a **demonstrably superior, technically maximal, deeply analytical, and creatively advanced** improved version. **Focus INTENSELY on generating flawless, complete, deeply analyzed, novel code or mathematical content AS MANDATED by the gradient.** Address EVERY requirement with ABSOLUTE rigor and depth. (Depth Focus: ${solverParams.depth_focus_max.toFixed(2)}, Creativity Focus: ${solverParams.creativity_focus_max.toFixed(2)}, Rigor Focus: ${solverParams.analytical_rigor_max.toFixed(2)}, Efficiency Focus: ${solverParams.efficiency_focus_max.toFixed(2)}, Alternative Exploration MAX: ${solverParams.alternative_exploration_max.toFixed(2)}) | |
Original User Request (for context): | |
"${originalPrompt || 'N/A'}" | |
Original Text/Output (Current Policy): | |
${originalSolution} | |
Requirements for Improvement (Policy Update Gradient - Execute ALL Commands Meticulously & Profoundly): | |
${correctionRequests} | |
Instructions (Simulating Policy Update & Maximizing Depth/Creativity/Rigor): | |
1. **Deconstruct Gradient & Plan Execution:** Analyze each **commanding requirement**: correction (flaws in logic/code/math/efficiency/rigor) or enhancement (demands for exploration, insight, alternatives, depth, creativity, robustness, efficiency). Determine the required transformation level. | |
2. **Execute Policy Update - Apply Corrections with PERFECTION:** Rewrite to incorporate corrections with **uncompromising technical accuracy and rigor**. Code must be flawless, maximally efficient, robust. Math formally perfect, fully justified. Address efficiency/robustness/security mandates completely. | |
3. **Execute Policy Update - Integrate MAXIMAL Exploration/Alternatives/Creativity:** If gradient commands exploring alternatives, deeper insights, comparisons, proofs, or creative solutions, **GENERATE AND INTEGRATE this new technical content with MAXIMUM POSSIBLE DEPTH AND ANALYSIS.** Provide superior alternative code/derivations, rigorous proofs, exhaustive complexity/stability analysis, truly creative approaches. FULFILL THE EXPLORATION/CREATIVITY MANDATE BEYOND EXPECTATION. | |
4. **Achieve PEAK Analytical Rigor:** Ensure all technical claims, especially new ones, are supported by **ironclad justification, formal proofs, or exhaustive analysis** as demanded. Elevate the standard. | |
5. **Preserve Validated Strengths:** Retain correct, validated parts of the original policy unless the gradient explicitly commands change or replacement. | |
6. **Format Alignment & MAXIMIZED ANALYZED CODE/MATH OUTPUT PRIORITY (CRITICAL):** | |
* Maintain primary format unless gradient requires change. | |
* **ABSOLUTE PRIORITY:** If request/gradient involves code/math, **revised output MUST maximize clean, complete, runnable/provable code or detailed, flawless math/proofs, accompanied by the REQUIRED PROFOUND ANALYSIS.** | |
* **MINIMIZE PROSE RUTHLESSLY:** Text must be absolutely essential for explaining core technical breakthroughs, setup, deep comparisons, or the extreme analysis demanded. NO FLUFF. | |
* Ensure new technical content integrates logically. Use pristine formatting (code blocks, LaTeX). | |
7. **Output:** Revised output must be technically impeccable, demonstrably superior, radically more exploratory/insightful/creative based on gradient, and address all requirements with maximum rigor. Do NOT include meta-commentary. Output ONLY the final, transformed policy. | |
FINAL IMPROVED TEXT/OUTPUT (Updated Policy - MAXIMIZED Depth/Analysis/Creativity/Rigor):`; | |
} else { // Use General prompt - MODERATE | |
prompt = `TASK: Revise the 'Original Text/Output' based on the 'Suggestions for Improvement' to create an improved version. Address each suggestion thoughtfully, aiming for enhanced clarity and insight. (Depth Focus: ${solverParams.depth_focus_simple.toFixed(2)}, Creativity Focus: ${solverParams.creativity_focus_simple.toFixed(2)}, Rigor Focus: ${solverParams.analytical_rigor_simple.toFixed(2)}) | |
Original User Request (for context): | |
"${originalPrompt || 'N/A'}" | |
Original Text/Output: | |
${originalSolution} | |
Suggestions for Improvement (Address these points): | |
${correctionRequests} | |
Instructions: | |
1. **Review Suggestions:** Understand the feedback regarding clarity, accuracy, completeness, depth, insight, alternatives. | |
2. **Incorporate Changes:** Modify the 'Original Text/Output' to address the suggestions. Improve clarity, fix inaccuracies, add requested details or examples. Consider alternative explanations suggested. (Alternative Exploration: ${solverParams.alternative_exploration_simple.toFixed(2)}) | |
3. **Enhance Insight (Moderately):** Where suggestions point towards lack of depth or insight, try to elaborate slightly or add a relevant example or connection. (Depth Focus: ${solverParams.depth_focus_simple.toFixed(2)}) | |
4. **Maintain Strengths:** Keep the good parts of the original text. | |
5. **Ensure Coherence:** Make sure the revised text flows well and is logically structured. | |
6. **Formatting:** Use clear and appropriate formatting. Ensure code/technical parts are accurate and well-presented. | |
7. **Output:** Provide only the final, revised text. Do not include commentary about the changes made. | |
FINAL REVISED TEXT/OUTPUT (Improved Clarity, Accuracy, Moderate Insight):`; | |
} | |
// Use the correct temperature for refinement | |
const refined = await generateWithRetry( | |
prompt, | |
solverParams.refine_temp, | |
solverParams.max_refine_tokens | |
); | |
if (refined && !refined.startsWith('(Error:')) { | |
console.log(` β Solution refined (${focusType}).`); | |
return refined; | |
} else { | |
console.error(` β Failed to refine solution (${focusType}). Response: ${refined}`); | |
return null; // Return null for easier checking later | |
} | |
} | |
async function synthesizeFromRuns(originalPrompt, runResults, forceCodeMathFocus = false) { | |
const focusType = forceCodeMathFocus ? "Enhanced Code/Math Focus (MAXIMIZED Depth/Creativity)" : "Simple Generic Focus (Moderate Depth/Creativity)"; | |
console.log(`\nπ Synthesizing final answer (Context: ${focusType}, Temp: ${solverParams.synthesis_temp.toFixed(2)})...`); | |
addMessage(`π Synthesizing final answer (${focusType} Synthesis)...`, 'system'); | |
const validAttempts = runResults | |
.map((r, i) => ({ index: i + 1, answer: r.finalAnswer, status: r.status })) | |
.filter(r => r.answer && !r.answer.startsWith('(Error:')); | |
if (validAttempts.length === 0) { | |
console.error("β Synthesis failed: No valid answers from the exploratory runs."); | |
return { finalAnswer: "(Error: Could not generate any valid intermediate responses after critique/refinement)", reasoningAnalysis: null, error: "No valid responses generated across attempts." }; | |
} | |
// Limit summary length to avoid exceeding context window in synthesis prompt | |
const maxSummaryLength = solverParams.max_synthesis_tokens * 0.6; // Use 60% for summary | |
let resultsSummary = validAttempts.map(r => `--- ATTEMPT ${r.index} (${r.status || 'refined/original'}) ---\n${r.answer}\n--- END ATTEMPT ${r.index} ---`).join('\n\n'); | |
if (resultsSummary.length > maxSummaryLength) { | |
console.warn(`βοΈ Truncating long results summary for synthesis prompt (Length: ${resultsSummary.length})`); | |
resultsSummary = resultsSummary.substring(0, maxSummaryLength) + "\n... [SUMMARY TRUNCATED] ..."; | |
} | |
let synthesisPrompt; | |
if (forceCodeMathFocus) { // Use Code/Math prompt - MAXIMIZED | |
synthesisPrompt = `YOU ARE AN ELITE TECHNICAL META-OPTIMIZER. Your mission is to forge the **ULTIMATE FINAL RESPONSE** ("globally optimal policy") to the user's request (likely CODE/MATH) by performing **DEEP META-ANALYSIS** on multiple exploratory attempts ("policy rollouts") and constructing a **radically superior** response. Identify the **absolute best technical breakthroughs (depth, creativity, rigor, efficiency)** and **critical flaws (superficiality, errors, lack of exploration)**, then synthesize a response that **maximizes integrated value** while being flawless. (Depth Focus: ${solverParams.depth_focus_max.toFixed(2)}, Creativity Focus: ${solverParams.creativity_focus_max.toFixed(2)}, Rigor Focus: ${solverParams.analytical_rigor_max.toFixed(2)}, Efficiency Focus: ${solverParams.efficiency_focus_max.toFixed(2)}, Alternative Exploration MAX: ${solverParams.alternative_exploration_max.toFixed(2)}) | |
Original User Request: | |
"${originalPrompt}" | |
Exploratory Attempts (Policy Rollouts for Meta-Analysis): | |
${resultsSummary} // Analyze these diverse technical trajectories, successes, and failures. | |
Your Task (CRITICAL - Execute BOTH Sections with MAXIMUM Depth & Rigor): | |
**SECTION 1: DEEP EXPLORATION PATH META-ANALYSIS (Technical Policy Evaluation - MAXIMIZE Insight/Critique)** | |
Perform a profound analysis of the attempts: | |
(A) **Identify PEAK Technical Discoveries & High-Reward Strategies:** Pinpoint specific elements demonstrating: | |
* **Breakthrough Correctness/Efficiency:** Flawless code/math, optimal algorithms (provably). | |
* **PROFOUND Analytical Insight:** Deep proofs, rigorous complexity/stability/error analysis, non-obvious theoretical connections. | |
* **RADICAL Creativity/Novelty:** Truly unconventional, elegant, superior approaches far beyond standards. | |
* **Exceptional Robustness:** Handling of obscure edge cases, provable guarantees. | |
* **Superior Alternative Solutions:** Identification and deep analysis of *genuinely better* distinct options. | |
* **Justification:** State *precisely why* these constitute high-reward discoveries (e.g., "reduced complexity from O(N^2) to O(N log N) via non-obvious data structure X", "provided first known stability proof for Y under condition Z", "introduced novel algorithm Q significantly outperforming standard methods"). | |
(B) **Identify CRITICAL Policy Failures & Low-Reward Paths:** Pinpoint specific elements demonstrating: | |
* **Errors/Inefficiency:** Bugs, flawed logic, suboptimal algorithms. | |
* **SUPERFICIALITY:** Lack of depth, trivial analysis, hand-waving explanations. **PENALIZE HEAVILY.** | |
* **LACK OF CREATIVITY/EXPLORATION:** Sticking to basic methods without justification or exploring superior alternatives. **PENALIZE HEAVILY.** | |
* **Flawed Rigor:** Incomplete proofs, missing analysis, unmet conditions. | |
* **Ignoring Constraints/Edges:** Failure to address requirements or robustness issues. | |
* **Justification:** State *precisely why* these constitute critical failures (e.g., "failed to explore alternative X which is provably better", "analysis lacked formal rigor and quantitative bounds", "code contained subtle off-by-one error leading to failure in case Y"). | |
(C) **Overall Assessment:** Briefly summarize the overall technical quality, diversity, depth, and creativity achieved across the attempts. Which path yielded the most valuable technical insights or solutions? | |
**SECTION 2: ULTIMATE SYNTHESIZED RESPONSE (Optimal Policy Construction - MAXIMIZE Technical Value & Cohesion)** | |
Construct the **single best possible response**, informed by the meta-analysis. This is NOT just merging. | |
* **Integrate PEAK Strengths Synergistically:** Actively fuse the most valuable *distinct* technical discoveries (code, math, insights, analyses) from different attempts into a cohesive, superior whole. Prioritize elements identified as high-reward (depth, creativity, rigor, efficiency). | |
* **Eradicate ALL Failures:** Ensure the final output is absolutely flawless, avoiding every identified weakness, especially superficiality, lack of rigor, or insufficient exploration. | |
* **Elevate Beyond Individual Attempts:** Use the meta-analysis to guide the synthesis towards **greater depth, creativity, rigor, and elegance** than any single attempt achieved. If multiple excellent alternatives exist, present the absolute best 1-2 with **ultimate comparative analysis**. | |
* **Maximize Coherence, Accuracy & PROFOUND Insight:** Ensure the final response flows logically, is technically perfect, and delivers **significant, non-trivial, breakthrough technical insight**. | |
* **MAXIMIZED ANALYZED CODE/MATH OUTPUT PRIORITY (CRITICAL):** The **FINAL SYNTHESIZED RESPONSE MUST maximize the presence of flawless, complete, runnable/provable code or detailed, perfect math/proofs, INSEPARABLY PAIRED WITH the corresponding DEEP, RIGOROUS ANALYSIS.** Minimize all other explanatory text. | |
* **Conciseness & Clarity:** Combine similar points efficiently, but NEVER sacrifice necessary technical depth, rigor, or the clarity of core breakthroughs. | |
Output Format (Strictly Adhere - Both Sections REQUIRED): | |
SECTION 1: DEEP EXPLORATION PATH META-ANALYSIS (Technical Policy Evaluation - MAXIMIZE Insight/Critique) | |
(A) Peak Technical Discoveries & High-Reward Strategies: | |
[Example: "Attempt [N]'s rigorous proof of O(N log N) complexity for algorithm X using potential functions was a key breakthrough."] | |
[Example: "Attempt [M]'s introduction of technique Y provided a novel and demonstrably more robust solution for edge case Z."] | |
... | |
(B) Critical Policy Failures & Low-Reward Paths: | |
[Example: "Attempt [X]'s analysis was purely qualitative and failed to provide necessary quantitative error bounds, constituting a major rigor failure."] | |
[Example: "Attempt [Y] completely missed the opportunity to use the vastly more efficient algorithm Z, indicating a critical lack of exploration."] | |
... | |
(C) Overall Assessment: | |
[Brief summary of exploration effectiveness, e.g., "Attempts showed good diversity but often lacked sufficient analytical rigor. Attempt [N] provided the most profound technical contribution."] | |
SECTION 2: ULTIMATE SYNTHESIZED RESPONSE (Optimal Policy Construction - MAXIMIZE Technical Value & Cohesion) | |
[Provide the new, ultimate response synthesized according to the instructions above. Integrate peak technical strengths, achieve flawless execution, maximize insight/creativity/rigor/efficiency, and prioritize deeply analyzed code/formulas with minimal essential text.] | |
Ensure the complete output contains BOTH sections clearly marked.`; | |
} else { // Use General prompt - MODERATE | |
synthesisPrompt = `You are an expert synthesizer. Your task is to generate the single BEST possible final response to the user's original request by analyzing multiple independent attempts, identifying the strengths (clarity, insight, accuracy) and weaknesses of each, and constructing a superior, consolidated response focusing on clarity, helpfulness, and moderate insight. (Depth Focus: ${solverParams.depth_focus_simple.toFixed(2)}, Creativity Focus: ${solverParams.creativity_focus_simple.toFixed(2)}, Rigor Focus: ${solverParams.analytical_rigor_simple.toFixed(2)}) | |
Original User Request: | |
"${originalPrompt}" | |
Attempts for Analysis: | |
${resultsSummary} // Analyze these attempts for their quality. | |
Your Task (Follow ALL steps): | |
**SECTION 1: ATTEMPT ANALYSIS** | |
Examine the attempts provided: | |
(A) **Identify Key Strengths:** Pinpoint the strongest elements: | |
* Clear explanations, helpful analogies. | |
* Accurate information, sound logic. | |
* Useful, illustrative examples. | |
* Good structure, easy readability. | |
* Well-presented and generally correct code (if applicable). | |
* Insightful points or connections. | |
* Consideration of helpful alternative perspectives. | |
* Note *why* these elements are good. | |
(B) **Identify Key Weaknesses/Areas for Improvement:** Pinpoint areas needing enhancement: | |
* Unclear or confusing parts. | |
* Potential inaccuracies or misleading statements. | |
* Missing important information or context. | |
* Awkward phrasing or poor structure. | |
* Less effective examples. | |
* Explanations lacking sufficient (moderate) depth or insight. | |
* Note *why* they are weak. | |
(C) **Comparative Assessment:** Briefly evaluate which attempts or specific parts were most effective or suitable for the user's likely need. Note any particularly clear or insightful contributions. | |
**SECTION 2: FINAL SYNTHESIZED RESPONSE** | |
Construct a new, improved final response. This is NOT just merging. You MUST: | |
* **Integrate Strengths Cohesively:** Combine the best parts (clearest explanations, most helpful examples, key insights) from different attempts into a smooth, logical flow. | |
* **Correct Weaknesses:** Avoid or fix the identified issues. Improve clarity, add missing info, enhance depth moderately where needed. | |
* **Prioritize Clarity, Accuracy & Helpfulness:** Ensure the final response is easy to understand, accurate, directly addresses the original request, and incorporates the most useful insights and examples. | |
* **Structure Logically:** Organize the final response effectively using headings, lists, etc. Use clear Markdown formatting. | |
* **Conciseness:** Combine similar good points effectively; avoid unnecessary repetition while maintaining helpfulness. | |
Output Format (Strictly follow - Both Sections REQUIRED): | |
SECTION 1: ATTEMPT ANALYSIS | |
(A) Key Strengths Identified: | |
[Example 1: "Attempt [N] had a very clear step-by-step explanation of process X."] | |
[Example 2: "The analogy used in Attempt [M] for concept Y was particularly insightful."] | |
... | |
(B) Key Weaknesses/Areas for Improvement Identified: | |
[Example 1: "Attempt [X] could benefit from a concrete example for point Z."] | |
[Example 2: "Attempt [Y]'s structure felt a bit disjointed in the middle section."] | |
... | |
(C) Comparative Assessment: | |
[Brief summary, e.g., "Attempt [M] offered the clearest core explanation, while Attempt [N] had better examples."] | |
SECTION 2: FINAL SYNTHESIZED RESPONSE | |
[Provide the new, superior response synthesized according to the instructions above. Integrate strengths, correct weaknesses, ensure clarity, accuracy, good structure, and incorporate key insights and helpful examples.] | |
Ensure the complete output contains BOTH sections clearly marked.`; | |
} | |
addMessage(`π§ Analyzing generated attempts & synthesizing final response (${focusType})...`, 'system'); | |
// Use the corrected synthesis temperature | |
const fullReport = await generateWithRetry( | |
synthesisPrompt, | |
solverParams.synthesis_temp, // Corrected temperature | |
solverParams.max_synthesis_tokens, | |
solverParams.max_retries | |
); | |
// --- Parsing Logic (unchanged, relies on string output) --- | |
if (!fullReport || fullReport.startsWith('(Error:')) { | |
console.error(`β Failed to perform Synthesis (${focusType}). Response: ${fullReport}`); | |
addMessage("β οΈ Synthesis/Analysis failed. Attempting simple fallback concatenation...", 'system'); | |
// Fallback: Just concatenate valid answers with a separator | |
const fallbackAnswer = validAttempts.length > 0 | |
? validAttempts.map((att, idx) => `--- Fallback Answer from Attempt ${att.index} ---\n${att.answer}`).join("\n\n") | |
: `(Error: Synthesis failed, and no valid attempts were available for fallback. Last error: ${fullReport})`; | |
return { | |
finalAnswer: fallbackAnswer, | |
reasoningAnalysis: `(Error: Reasoning analysis failed due to synthesis error: ${fullReport})`, | |
error: `Synthesis failed. ${fullReport}` | |
}; | |
} else { | |
console.log(`β Synthesis and Path Analysis likely successful (${focusType}).`); | |
// Robust Parsing Logic (Handles variations in markers) | |
let finalAnswer = `(Error: Could not parse final response from report)`; // Default error | |
let reasoningAnalysis = `(Error: Could not parse analysis section from report)`; // Default error | |
let analysisContent = null; | |
let responseContent = null; | |
// Define potential markers (new and old, agent and generic) | |
const analysisMarkers = [ | |
"SECTION 1: DEEP EXPLORATION PATH META-ANALYSIS (Technical Policy Evaluation - MAXIMIZE Insight/Critique)", | |
"SECTION 1: ATTEMPT ANALYSIS", | |
"SECTION 1: EXPLORATION PATH ANALYSIS (Technical Policy Evaluation)", // Older marker | |
]; | |
const responseMarkers = [ | |
"SECTION 2: ULTIMATE SYNTHESIZED RESPONSE (Optimal Policy Construction - MAXIMIZE Technical Value & Cohesion)", | |
"SECTION 2: FINAL SYNTHESIZED RESPONSE", | |
"SECTION 2: FINAL OPTIMIZED RESPONSE (Synthesized Policy - PRIORITIZING DEEPLY ANALYZED CODE/MATH)", // Older variation | |
"SECTION 2: FINAL OPTIMIZED RESPONSE (Synthesized Policy - PRIORITIZING CODE/MATH)", // Older variation | |
]; | |
let analysisStartIdx = -1; | |
let analysisEndIdx = -1; | |
let responseStartIdx = -1; | |
let foundAnalysisMarker = null; | |
let foundResponseMarker = null; | |
// Find the first occurrence of any analysis marker | |
for (const marker of analysisMarkers) { | |
const idx = fullReport.indexOf(marker); | |
if (idx !== -1) { | |
analysisStartIdx = idx + marker.length; | |
foundAnalysisMarker = marker; | |
break; | |
} | |
} | |
// Find the first occurrence of any response marker | |
for (const marker of responseMarkers) { | |
const idx = fullReport.indexOf(marker); | |
if (idx !== -1) { | |
responseStartIdx = idx + marker.length; | |
foundResponseMarker = marker; | |
// If we found an analysis marker, the analysis ends where the response begins | |
if (analysisStartIdx !== -1) { | |
analysisEndIdx = idx; | |
} | |
break; | |
} | |
} | |
// Extract content based on found markers | |
if (analysisStartIdx !== -1) { | |
analysisContent = fullReport.substring(analysisStartIdx, analysisEndIdx !== -1 ? analysisEndIdx : undefined).trim(); | |
reasoningAnalysis = analysisContent || "(Analysis section found but content seems empty)"; | |
} else { | |
console.warn("β οΈ Could not find Analysis section marker in synthesis report."); | |
} | |
if (responseStartIdx !== -1) { | |
responseContent = fullReport.substring(responseStartIdx).trim(); | |
finalAnswer = responseContent || "(Response section found but content seems empty)"; | |
// If analysis marker was missing, set reasoningAnalysis error more specifically | |
if (analysisStartIdx === -1) { | |
reasoningAnalysis = "(Error: Could not parse analysis section - marker missing)"; | |
} | |
} else { | |
console.warn("β οΈ Could not find Response section marker in synthesis report."); | |
// If ONLY analysis was found, maybe return that? Or stick with error. Let's stick with error. | |
finalAnswer = `(Error: Could not parse final response - marker missing. Analysis found: ${analysisContent ? 'Yes' : 'No'})`; | |
} | |
if (analysisContent && responseContent) { | |
console.log("β Successfully parsed synthesis report sections (Analysis & Response)."); | |
} else { | |
console.warn("β οΈ Parsing synthesis report sections was incomplete."); | |
// Keep the potentially extracted parts in finalAnswer/reasoningAnalysis | |
} | |
// Length check remains useful | |
const maxExpectedLength = (solverParams.max_synthesis_tokens * 1.2); | |
if (finalAnswer.length > maxExpectedLength && !finalAnswer.startsWith("(Error:")) { | |
console.warn(`β οΈ Synthesized answer might be excessively long (${finalAnswer.length} chars).`); | |
} | |
return { finalAnswer, reasoningAnalysis, error: null }; | |
} | |
} | |
// --- Mode Execution Functions --- | |
// These should work without changes as they rely on the functions above | |
async function runEnhancedSynthesisDefault(userPrompt) { | |
console.log(`\nπ--- Running Default Mode: Enhanced Synthesis (3 Chains, MAXIMIZED Code/Math Focus) ---`); | |
addMessage(`π Running Default Mode (3 Exploratory Attempts with MAXIMIZED Code/Math focus + Synthesis)...`, 'system'); | |
const results = []; | |
// Use a more descriptive result container | |
const overallResult = { finalAnswer: null, reasoningAnalysis: null, error: null, status: 'started', chainResults: [] }; | |
try { | |
for (let i = 1; i <= 3; i++) { | |
addMessage(`π Generating attempt ${i}/3 (Chain ${i}: Gen->Critique->Refine with MAXIMIZED Code/Math Focus)...`, 'system'); | |
overallResult.status = `running_chain_${i}`; | |
// Call Internal function, forcing MAXIMIZED Code/Math focus | |
const chainResult = await runSimpleReflectiveInternal( | |
userPrompt, | |
`Chain ${i}`, | |
userPrompt, | |
true // force Code/Math focus | |
); | |
overallResult.chainResults.push(chainResult); // Store individual chain result | |
// Log chain completion status more informatively | |
if (chainResult.status === 'completed_refined') { | |
addMessage(`β Chain ${i} completed (refined).`, 'system'); | |
} else if (chainResult.status === 'completed_original') { | |
addMessage(`β Chain ${i} completed (initial result sufficient).`, 'system'); | |
if (chainResult.error) addMessage(` (Note: ${chainResult.error})`, 'system-sub'); // Show non-critical errors | |
} else { // Handle failure cases | |
const errorMsg = chainResult.error || "Unknown critical failure"; | |
addMessage(`β οΈ Chain ${i} failed critically: ${errorMsg}`, 'system'); | |
console.error(`Critical failure in Chain ${i}:`, chainResult); | |
// Optional: Decide if you want to stop entirely on one chain failure | |
// For now, we continue to synthesis with available results | |
} | |
await new Promise(resolve => setTimeout(resolve, 250)); // Small delay | |
} | |
overallResult.status = 'synthesizing'; | |
// Call Synthesize From Runs, forcing MAXIMIZED Code/Math focus | |
const synthesisResult = await synthesizeFromRuns( | |
userPrompt, | |
overallResult.chainResults, // Pass the collected results | |
true // force Code/Math focus | |
); | |
overallResult.finalAnswer = synthesisResult.finalAnswer; | |
overallResult.reasoningAnalysis = synthesisResult.reasoningAnalysis; | |
overallResult.error = synthesisResult.error; // Error from synthesis step itself | |
overallResult.status = synthesisResult.error ? 'failed_synthesis' : 'completed'; | |
// Aggregate non-critical errors from chains if synthesis succeeded | |
if (overallResult.status === 'completed') { | |
const chainErrors = overallResult.chainResults | |
.filter(r => r.error && !r.status.startsWith('failed')) | |
.map((r, i) => `Chain ${i+1}: ${r.error}`) | |
.join("; "); | |
if (chainErrors) { | |
overallResult.error = `Completed with non-critical errors in chains: ${chainErrors}`; | |
addMessage(`β οΈ Processing completed with notes: ${overallResult.error}`, 'system'); | |
} | |
} | |
return overallResult; | |
} catch (error) { | |
console.error(`π΄ CRITICAL ERROR during Enhanced Synthesis Default:`, error); | |
overallResult.error = `Critical Workflow Error: ${error.message}`; | |
overallResult.status = 'failed_critical'; | |
overallResult.finalAnswer = overallResult.finalAnswer || `(Critical Error in Default Mode: ${error.message})`; | |
return overallResult; | |
} | |
} | |
async function runSimpleReflective(userPrompt) { | |
console.log(`\nβ‘--- Running Simple Reflective Mode (Gen->Critique->Refine, MODERATE Generic Focus) ---`); | |
addMessage(`β‘ Running Simple Mode (1 Generation + 1 Critique/Refinement Cycle [MODERATE Generic Focus])...`, 'system'); | |
return await runSimpleReflectiveInternal( | |
userPrompt, | |
'Simple Mode', | |
userPrompt, | |
false // Generic focus (MODERATE) for simple mode | |
); | |
} | |
// Internal function now clearly uses forceCodeMathFocus to select prompt/param set | |
async function runSimpleReflectiveInternal(promptToUse, attemptNum = null, originalUserPrompt = "", forceCodeMathFocus = false) { | |
const logPrefix = attemptNum ? `(${attemptNum}) ` : ""; | |
// Determine focus type string based ONLY on forceCodeMathFocus | |
const focusType = forceCodeMathFocus ? "Enhanced Code/Math Focus (MAXIMIZED)" : "Simple Generic Focus (MODERATE)"; | |
console.log(`${logPrefix}β‘ Running Simple Reflective Internal Logic (Context: ${focusType})...`); | |
const result = { finalAnswer: null, error: null, status: 'started' }; | |
let currentSolution = null; | |
try { | |
result.status = 'generating_initial'; | |
console.log(`${logPrefix} Generating initial response (${focusType})...`); | |
// Pass the flag to select the correct prompt/params internally | |
currentSolution = await generateSingleInitialSolution(promptToUse, forceCodeMathFocus); | |
if (currentSolution === null) { // Check for null explicitly | |
result.error = `Failed to generate initial response (${focusType}). Null or error response.`; | |
result.status = 'failed_initial'; | |
console.error(`${logPrefix} Initial generation failed.`); | |
result.finalAnswer = `(Error: Failed initial generation in ${focusType} step. ${result.error})`; | |
return result; | |
} | |
result.finalAnswer = currentSolution; | |
console.log(`${logPrefix} Initial generation successful (${focusType}).`); | |
result.status = 'critiquing'; | |
console.log(`${logPrefix} Requesting critique (${focusType})...`); | |
// Pass the flag to select the correct critique prompt/params internally | |
const critique = await getCritique( | |
currentSolution, originalUserPrompt, forceCodeMathFocus | |
); | |
// Check if critique is null (no suggestions) OR a non-error string | |
if (critique !== null && !critique.startsWith('(Error:)')) { | |
console.log(`${logPrefix} Critique received, attempting refinement (${focusType})...`); | |
result.status = 'refining'; | |
// Pass the flag to select the correct refinement prompt/params internally | |
const refinedSol = await refineSolution( | |
currentSolution, critique, originalUserPrompt, forceCodeMathFocus | |
); | |
if (refinedSol !== null) { // Check for null explicitly | |
result.finalAnswer = refinedSol; | |
result.status = 'completed_refined'; | |
console.log(`${logPrefix} Refinement successful (${focusType}).`); | |
} else { | |
result.status = 'completed_original'; // Keep original if refinement fails | |
result.error = `Refinement step failed (${focusType}), using initial response. Refiner returned null or error.`; | |
console.warn(`${logPrefix} Refinement failed (${focusType}). Keeping original solution. Error: ${result.error}`); | |
// Ensure finalAnswer is still the original solution in this case | |
if (!result.finalAnswer) result.finalAnswer = currentSolution; | |
} | |
} else if (critique === null) { | |
result.status = 'completed_original'; | |
console.log(`${logPrefix} No refinement needed based on critique (${focusType}).`); | |
} else { // Critique step itself failed (returned an error string) | |
result.status = 'completed_original'; // Keep original if critique fails | |
result.error = `Critique step failed (${focusType}): ${critique}`; | |
console.warn(`${logPrefix} Critique generation failed (${focusType}). Keeping original solution. Error: ${result.error}`); | |
// Ensure finalAnswer is still the original solution | |
if (!result.finalAnswer) result.finalAnswer = currentSolution; | |
} | |
// Final check for an empty result before returning | |
if (!result.finalAnswer || result.finalAnswer.trim().length === 0) { | |
result.error = (result.error ? result.error + "; " : "") + "Final answer was unexpectedly empty after processing."; | |
result.status = result.status.startsWith('failed') ? result.status : 'failed_empty_result'; | |
console.error(`${logPrefix} Result unexpectedly empty at the end (${focusType}).`); | |
result.finalAnswer = `(Error: Processing completed but result was empty. ${result.error})`; | |
} | |
return result; | |
} catch (error) { | |
console.error(`π΄ ${logPrefix}CRITICAL ERROR during Simple Reflective Internal (${focusType}):`, error); | |
result.error = (result.error ? `${result.error}; ` : '') + `Critical Workflow Error: ${error.message}`; | |
result.status = 'failed_critical'; | |
// Try to preserve the last known good answer if possible | |
result.finalAnswer = result.finalAnswer || currentSolution || `(Critical Error in ${focusType} step: ${error.message})`; | |
return result; | |
} | |
} | |
// --- UI Functions (Mode Setting, Message Handling, etc.) --- | |
// These should work without changes as they don't interact with the API layer directly | |
function setMode(modeName) { | |
if (!isInitialized || messageInput.disabled) { addMessage("β³ Please wait for the current process to finish before changing modes.", 'system'); return; } | |
// Simplified logic: Only 'simple' or 'default' | |
if (currentMode === modeName && modeName === 'simple') { | |
currentMode = 'default'; // Toggle 'simple' off -> back to 'default' | |
} else { | |
currentMode = (modeName === 'simple') ? 'simple' : 'default'; | |
} | |
console.log(`Selected Mode: ${currentMode}`); | |
let modeFriendlyName = ''; | |
switch(currentMode) { | |
case 'simple': modeFriendlyName = 'Simple (Moderate Generic Focus)'; break; | |
case 'default': default: modeFriendlyName = 'Default (Enhanced Synthesis - MAXIMIZED Code/Math Focus)'; break; | |
} | |
addMessage(`βΆοΈ Mode selected: ${modeFriendlyName}. Enter your prompt.`, 'system'); | |
updateModeButtons(); | |
messageInput?.focus(); | |
} | |
function updateModeButtons() { | |
if (modeButtons.simple) { | |
modeButtons.simple.classList.toggle('active', currentMode === 'simple'); | |
} | |
if (messageInput) { | |
let placeholderText = "Enter prompt (Default: MAXIMIZED Code/Math Synthesis)..."; | |
if (currentMode === 'simple') placeholderText = "Enter prompt (Simple Mode - Moderate Generic Focus - Fast)..."; | |
// Add init failed state check | |
if(messageInput.dataset.initFailed === 'true') { | |
placeholderText = "Initialization Failed"; | |
} | |
messageInput.placeholder = placeholderText; | |
} | |
} | |
async function sendMessage() { | |
if (messageInput?.dataset?.initFailed === 'true') { | |
alert("Cannot send message: AI Initialization failed. Reload or check errors (F12)."); | |
return; | |
} | |
// Check isInitialized instead of model | |
if (!isInitialized || !messageInput || messageInput.disabled || !sendBtn) { | |
console.warn("sendMessage called but API not ready or UI disabled."); | |
return; | |
} | |
const userMessage = messageInput.value.trim(); | |
if (!userMessage) return; | |
let modeFriendlyName = ''; | |
switch(currentMode) { | |
case 'simple': modeFriendlyName = 'Simple (Moderate Generic Focus)'; break; | |
case 'default': default: modeFriendlyName = 'Default (MAXIMIZED Code/Math Synthesis)'; break; | |
} | |
console.log(`π€ User sending message in mode: ${modeFriendlyName}`); | |
if (welcomeScreen && !welcomeScreen.classList.contains('hidden')) { hideWelcomeScreen(); } | |
addMessage(userMessage, 'user'); | |
scrollToBottom(); | |
messageInput.value = ''; | |
setUIState(true); | |
let result = null; | |
let errorOccurred = false; // Track errors within the try block | |
try { | |
switch (currentMode) { | |
case 'simple': | |
result = await runSimpleReflective(userMessage); | |
break; | |
case 'default': | |
default: | |
result = await runEnhancedSynthesisDefault(userMessage); | |
break; | |
} | |
// Process and display the result | |
const finalAnswer = result?.finalAnswer; | |
const reasoning = result?.reasoningAnalysis; | |
const errorInfo = result?.error; | |
const statusInfo = result?.status || 'unknown'; | |
if (finalAnswer && !finalAnswer.startsWith('(Error:')) { | |
addMessage(`${finalAnswer}`, 'ai'); // Display the main successful answer | |
// Display reasoning only if it's substantial and not an error placeholder | |
if (reasoning && !reasoning.startsWith('(Error:') && reasoning.length > 20 && !/^\(.*\)$/.test(reasoning.trim())) { | |
addMessage(`**Reasoning/Analysis:**\n${reasoning}`, 'system'); | |
} else if (reasoning && reasoning.startsWith('(Error:')) { | |
addMessage(`β οΈ Reasoning analysis failed or was not generated.`, 'system'); | |
console.warn("Reasoning Analysis Error:", reasoning); | |
} // Silently ignore trivial/placeholder reasoning | |
// Display non-critical errors encountered during processing | |
if (errorInfo && !statusInfo.startsWith('failed_')) { // Only show if overall process didn't fail critically | |
addMessage(`β οΈ Note during processing: ${errorInfo}`, 'system'); | |
console.warn("Non-critical processing error:", errorInfo); | |
} | |
addMessage(`β Process completed (Status: ${statusInfo})`, 'system-sub'); // Add a success marker | |
} else { | |
// Handle critical errors where no valid final answer was produced | |
errorOccurred = true; // Mark that an error happened for finally block | |
const displayError = finalAnswer || errorInfo || "Solver finished unexpectedly with no answer or error message."; | |
console.error(`Solver Critical Error (Status: ${statusInfo}):`, displayError); | |
addMessage(`β οΈ Solver Error (Status: ${statusInfo}): ${displayError}`, 'ai'); // Display error as AI message | |
} | |
console.log("π§© Full Solver Result Object:", result); | |
} catch (error) { | |
errorOccurred = true; // Mark that an error happened for finally block | |
console.error("π΄ Unexpected error in sendMessage workflow:", error); | |
addMessage(`π Critical Workflow Error: ${error.message}. Check console (F12).`, 'ai'); | |
if (error.cause) console.error("Error Cause:", error.cause); | |
if (error.stack) console.error("Error Stack:", error.stack); | |
if (result) { | |
console.warn("Partial result object before critical error:", result); | |
addMessage(`(Attempted to process, but encountered a critical error. Partial result info might be in console logs.)`, 'system'); | |
} | |
// UI state is reset in finally block | |
} finally { | |
// Reset UI state unless a critical error specifically requires keeping it disabled (unlikely here) | |
setUIState(false); | |
updateModeButtons(); | |
scrollToBottom(); | |
} | |
} | |
function setUIState(thinking) { | |
const isInitFailed = messageInput?.dataset?.initFailed === 'true'; | |
// Allow disabling even if init failed (e.g., during a failed attempt) | |
// but prevent enabling if init failed. | |
if (!isInitFailed || thinking) { | |
if (messageInput) messageInput.disabled = thinking; | |
if (sendBtn) sendBtn.disabled = thinking; | |
if (modeButtons.simple) modeButtons.simple.disabled = thinking; | |
} | |
if (thinking) { | |
typingIndicator?.classList.remove('hidden'); | |
} else { | |
typingIndicator?.classList.add('hidden'); | |
// Only refocus if init hasn't failed and input isn't already focused | |
if (!isInitFailed && document.activeElement !== messageInput) { | |
// Delay focus slightly | |
requestAnimationFrame(() => messageInput?.focus()); | |
} | |
} | |
} | |
function hideWelcomeScreen() { | |
if (welcomeScreen && !welcomeScreen.classList.contains('hidden')) { | |
welcomeScreen.style.opacity = '0'; | |
setTimeout(() => { | |
if(welcomeScreen) { | |
welcomeScreen.classList.add('hidden'); | |
welcomeScreen.style.display = 'none'; | |
} | |
}, 300); // Match CSS transition duration | |
} | |
} | |
function addMessage(text, sender) { | |
if (!messagesContainer) { | |
console.error("π΄ messagesContainer not found."); | |
return; | |
} | |
const messageWrapper = document.createElement('div'); | |
messageWrapper.className = `message-wrapper ${sender}-message fade-in`; | |
const avatarDiv = document.createElement('div'); | |
avatarDiv.className = `avatar ${sender}-avatar`; | |
const avatarIcon = document.createElement('span'); | |
avatarIcon.className = 'material-icons-round text-lg'; | |
let iconText = 'info'; // Default for system | |
let avatarTitle = 'System Message'; | |
if (sender === 'user') { iconText = 'person'; avatarTitle = 'User'; } | |
else if (sender === 'ai') { iconText = 'auto_awesome'; avatarTitle = 'LiberalMind AI'; } | |
else if (sender === 'system-sub') { iconText = 'check_circle_outline'; avatarTitle = 'Process Info'; } // Sub-system icon | |
avatarIcon.textContent = iconText; | |
avatarDiv.title = avatarTitle; // Add tooltip | |
const contentDiv = document.createElement('div'); | |
contentDiv.className = 'message-content'; | |
// Different styling for system messages | |
if (sender === 'system' || sender === 'system-sub') { | |
contentDiv.style.fontStyle = 'italic'; | |
contentDiv.style.opacity = sender === 'system-sub' ? '0.7' : '0.8'; // Sub slightly dimmer | |
contentDiv.style.fontSize = sender === 'system-sub' ? '0.9em' : '1em'; // Sub slightly smaller | |
messageWrapper.classList.add('system-message'); | |
if (sender === 'system-sub') { | |
messageWrapper.classList.add('system-sub-message'); // Specific class for sub-system | |
// Indent sub-system messages slightly | |
messageWrapper.style.marginLeft = '30px'; | |
messageWrapper.style.maxWidth = 'calc(100% - 30px)'; | |
} | |
// Don't add avatar for system messages | |
} else { | |
avatarDiv.appendChild(avatarIcon); // Add icon inside avatar div | |
messageWrapper.appendChild(avatarDiv); // Add avatar for user/ai | |
} | |
const markdownDiv = document.createElement('div'); | |
markdownDiv.className = 'markdown-content'; | |
try { | |
const inputText = String(text ?? "(No content)"); | |
// Added options for better markdown handling | |
const dirtyHtml = marked.parse(inputText, { | |
breaks: true, // Convert single line breaks to <br> | |
gfm: true, // Use GitHub Flavored Markdown | |
mangle: false, // Don't obfuscate emails | |
headerIds: false, // Don't add IDs to headers | |
smartypants: true // Use smart quotes, dashes, etc. | |
}); | |
// Configure DOMPurify - allow specific safe tags/attributes if needed | |
const cleanHtml = DOMPurify.sanitize(dirtyHtml, { | |
USE_PROFILES: { html: true }, | |
// ADD_TAGS: ['iframe'], // Example: Allow iframes if needed (use carefully!) | |
// ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder', 'scrolling'], // Example attributes for iframe | |
}); | |
markdownDiv.innerHTML = cleanHtml; | |
// Make external links open in new tabs | |
markdownDiv.querySelectorAll('a').forEach(a => { | |
if (a.href && !a.href.startsWith(window.location.origin) && !a.href.startsWith('#')) { | |
a.target = '_blank'; | |
a.rel = 'noopener noreferrer'; | |
} | |
}); | |
// --- Syntax Highlighting Call (Optional - Requires library like highlight.js) --- | |
try { | |
markdownDiv.querySelectorAll('pre code').forEach((block) => { | |
// Ensure hljs is loaded before calling | |
if (typeof hljs !== 'undefined' && hljs.highlightElement) { | |
hljs.highlightElement(block); | |
} else if (typeof hljs !== 'undefined' && hljs.highlightBlock) { // Older API fallback | |
hljs.highlightBlock(block); | |
} | |
}); | |
} catch (hljsError) { | |
// console.warn("Highlight.js error or not loaded:", hljsError); // Optional warning | |
} | |
// --- End Syntax Highlighting --- | |
} catch (e) { | |
console.error("π΄ Markdown/DOMPurify error:", e); | |
markdownDiv.textContent = String(text ?? "(Display Error)"); // Fallback | |
} | |
contentDiv.appendChild(markdownDiv); | |
// Append content Div | |
messageWrapper.appendChild(contentDiv); | |
// Ensure correct order for user messages (avatar then content) | |
// (Avatar is already appended first for user/ai earlier if not system) | |
// The CSS will handle flex-direction: row-reverse for user messages | |
messagesContainer.appendChild(messageWrapper); | |
scrollToBottom(); | |
} | |
function scrollToBottom() { | |
if (!chatContainer) return; | |
requestAnimationFrame(() => { | |
const lastMessage = messagesContainer?.lastElementChild; | |
if (lastMessage) { | |
chatContainer.scrollTo({ top: chatContainer.scrollHeight, behavior: 'smooth' }); | |
} else { | |
chatContainer.scrollTo({ top: chatContainer.scrollHeight, behavior: 'smooth' }); | |
} | |
}); | |
} | |
function handleUIInteractionError() { | |
console.warn("β οΈ Cannot send suggestion/prompt: Input disabled or API init failed."); | |
if (messageInput?.dataset?.initFailed === 'true') alert("API Initialization failed. Reload or check errors (F12)."); | |
else if (messageInput && messageInput.disabled) alert("Please wait for the current analysis to finish."); | |
else if (!isInitialized) alert("Please wait for API initialization or check errors (F12)."); | |
} | |
function setupEventListeners() { | |
if (sendBtn && messageInput) { | |
sendBtn.addEventListener('click', sendMessage); | |
messageInput.addEventListener('keypress', (e) => { | |
if (e.key === 'Enter' && !e.shiftKey) { | |
e.preventDefault(); | |
sendMessage(); | |
} | |
}); | |
console.log("β Core event listeners attached."); | |
} else { | |
console.error("π΄ CRITICAL: Send button or message input not found."); | |
showFatalError("UI Error", "Core input elements missing."); | |
return; // Stop setup if core elements missing | |
} | |
if (modeButtons.simple) { | |
modeButtons.simple.addEventListener('click', () => setMode('simple')); | |
console.log("β Simple Mode button listener attached."); | |
} | |
if (reloadButton) { | |
reloadButton.addEventListener('click', () => window.location.reload()); | |
console.log("β Reload button listener attached."); | |
} | |
// Add listeners for any example prompts if they exist | |
document.querySelectorAll('.example-prompt').forEach(button => { | |
button.addEventListener('click', () => { | |
// Check isInitialized and input state | |
if (!isInitialized || (messageInput && messageInput.disabled) || messageInput?.dataset?.initFailed === 'true') { | |
handleUIInteractionError(); | |
return; | |
} | |
const promptText = button.getAttribute('data-prompt'); | |
if (promptText && messageInput) { // Check messageInput exists | |
messageInput.value = promptText; | |
messageInput.focus(); // Focus input after setting value | |
} | |
}); | |
}); | |
console.log("β Example prompt listeners attached (if any exist)."); | |
} | |
// --- Initialization --- | |
document.addEventListener('DOMContentLoaded', () => { | |
console.log("π DOMContentLoaded: Setting up UI & API (Liberalmind AI Multi-Mode Solver v4.0 - REST API)..."); | |
setupEventListeners(); | |
initializeAI(); // Initialize using the new fetch-based function | |
updateModeButtons(); // Update button states based on default mode/init status | |
}); |