|
|
|
import React, { useState, useEffect } from 'react'; |
|
|
|
function App() { |
|
|
|
const [puzzleIndex, setPuzzleIndex] = useState(0); |
|
const [puzzleText, setPuzzleText] = useState(""); |
|
const [expectedSolution, setExpectedSolution] = useState(null); |
|
|
|
|
|
const [sysContent, setSysContent] = useState(""); |
|
|
|
|
|
const [generatedCode, setGeneratedCode] = useState(""); |
|
const [executionSuccess, setExecutionSuccess] = useState(null); |
|
const [attempts, setAttempts] = useState(0); |
|
const [isSolving, setIsSolving] = useState(false); |
|
const [problematicConstraints, setProblematicConstraints] = useState(""); |
|
|
|
|
|
useEffect(() => { |
|
fetch(`/default_sys_content`) |
|
.then(res => res.json()) |
|
.then(data => { |
|
if(data.success) { |
|
setSysContent(data.sysContent); |
|
} |
|
}) |
|
.catch(e => console.error(e)); |
|
}, []); |
|
|
|
|
|
useEffect(() => { |
|
fetch(`/get_puzzle?index=${puzzleIndex}`) |
|
.then(res => res.json()) |
|
.then(data => { |
|
if(data.success) { |
|
setPuzzleText(data.puzzle); |
|
setExpectedSolution(data.expected_solution); |
|
} else { |
|
console.error("Failed to fetch puzzle", data.error); |
|
setPuzzleText(""); |
|
setExpectedSolution(null); |
|
} |
|
}) |
|
.catch(e => console.error(e)); |
|
}, [puzzleIndex]); |
|
|
|
const handleSolve = () => { |
|
if(!puzzleText || !expectedSolution) { |
|
alert("puzzle or expectedSolution incomplete"); |
|
return; |
|
} |
|
const payload = { |
|
index: puzzleIndex, |
|
puzzle: puzzleText, |
|
expected_solution: expectedSolution, |
|
sys_content: sysContent, |
|
problematic_constraints: problematicConstraints |
|
}; |
|
|
|
setIsSolving(true); |
|
|
|
fetch(`/solve`, { |
|
method: "POST", |
|
headers: { "Content-Type": "application/json" }, |
|
body: JSON.stringify(payload) |
|
}) |
|
.then(res => res.json()) |
|
.then(data => { |
|
if(!data.success) { |
|
alert("Backend error: " + data.error); |
|
return; |
|
} |
|
const result = data.result; |
|
setGeneratedCode(result.generatedCode || ""); |
|
setExecutionSuccess(result.success); |
|
setAttempts(result.attempts || 0); |
|
setProblematicConstraints(result.problematicConstraints || ""); |
|
}) |
|
.catch(e => console.error(e)) |
|
.finally(() => { |
|
setIsSolving(false); |
|
}); |
|
}; |
|
|
|
return ( |
|
<div style={{ margin: 20 }}> |
|
<h1>Zebra Puzzle Demo</h1> |
|
|
|
<div style={{ marginBottom: 20 }}> |
|
<label>Choose puzzle index (0 - 999): </label> |
|
<input |
|
type="number" |
|
value={puzzleIndex} |
|
onChange={(e) => setPuzzleIndex(Number(e.target.value))} |
|
min={0} |
|
max={999} |
|
/> |
|
<button onClick={() => setPuzzleIndex(puzzleIndex)}>Load Puzzle</button> |
|
</div> |
|
|
|
<div style={{ marginBottom: 20 }}> |
|
<h3>Puzzle Text</h3> |
|
<pre>{puzzleText}</pre> |
|
<h3>Expected Solution</h3> |
|
<pre>{JSON.stringify(expectedSolution, null, 2)}</pre> |
|
</div> |
|
|
|
<div style={{ marginBottom: 20 }}> |
|
<h3>sys_content</h3> |
|
<textarea |
|
rows={10} |
|
cols={80} |
|
value={sysContent} |
|
onChange={(e) => setSysContent(e.target.value)} |
|
/> |
|
</div> |
|
|
|
<div style={{ marginBottom: 20 }}> |
|
<button onClick={handleSolve} disabled={isSolving}>Solve Puzzle with LLM</button> |
|
</div> |
|
|
|
<div> |
|
<h2>Result</h2> |
|
<p>Success: {executionSuccess === null ? "N/A" : executionSuccess ? "✅" : "❌"}</p> |
|
<p>Attempts: {attempts}</p> |
|
<h3>Issues</h3> |
|
<pre>{problematicConstraints}</pre> |
|
<h3>Generated Code</h3> |
|
<pre>{generatedCode}</pre> |
|
</div> |
|
</div> |
|
); |
|
} |
|
|
|
export default App; |
|
|