branch:
client.tsx
6633 bytesRaw
import { useAgent } from "agents/react";
import { useState } from "react";
import { createRoot } from "react-dom/client";
import type { Attempt, CFAgentState, MyAgent } from "./server";
function App() {
const [description, setDescription] = useState<string>("");
const [attempts, setAttempts] = useState<Attempt[]>([]);
const [status, setStatus] = useState<string>();
const [chosenSlogan, setChosenSlogan] = useState<string>();
const [attemptsExpanded, setAttemptsExpanded] = useState<boolean>(false);
console.log("[Client] Current description:", description);
const agent = useAgent<MyAgent, CFAgentState>({
agent: "my-agent",
name: "slogan-generator",
onStateUpdate(state, source) {
console.log("[Client] onStateUpdate called ", source);
setAttempts(state.attempts);
setChosenSlogan(state.chosenSlogan);
setStatus(state.status);
}
});
const handleGenerate = async () => {
if (description) {
console.log("[Client] Using agent stup to generate slogan:", description);
await agent.stub.generateSlogan(description);
} else {
console.log(
"[Client] Attempted to generateSlogan with empty description"
);
}
};
const handleDescriptionChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newDescription = e.target.value;
console.log("[Client] Description input changed:", newDescription);
setDescription(newDescription);
if (attempts.length > 0) {
// Reset the run
agent.stub.reset();
}
};
return (
<div style={{ fontFamily: "Arial, sans-serif", padding: "20px" }}>
<h1 style={{ color: "#333", marginBottom: "20px" }}>LLM As a Judge</h1>
<div style={{ marginBottom: "20px" }}>
<input
type="text"
value={description || ""}
onChange={handleDescriptionChange}
placeholder="Describe your product..."
style={{
border: "1px solid #ddd",
borderRadius: "4px",
fontSize: "16px",
marginRight: "8px",
padding: "8px 12px",
width: "300px"
}}
/>
<button
type="button"
onClick={handleGenerate}
style={{
backgroundColor: "#007bff",
border: "none",
borderRadius: "4px",
color: "white",
cursor: "pointer",
fontSize: "16px",
padding: "8px 16px"
}}
>
Generate Slogan
</button>
</div>
{status && <div>{status}</div>}
{chosenSlogan && (
<div
style={{
backgroundColor: "#f8f9fa",
border: "3px solid #28a745",
borderRadius: "12px",
padding: "24px",
margin: "20px 0",
textAlign: "center",
boxShadow: "0 8px 16px rgba(0,0,0,0.1)",
background: "linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%)"
}}
>
<h2
style={{
color: "#2c3e50",
fontSize: "28px",
fontWeight: "bold",
margin: "0",
textShadow: "2px 2px 4px rgba(0,0,0,0.1)"
}}
>
🎯 {chosenSlogan}
</h2>
<p
style={{
color: "#34495e",
fontSize: "16px",
fontStyle: "italic",
margin: "8px 0 0 0"
}}
>
Selected Winner
</p>
</div>
)}
{attempts.length > 0 && (
<div style={{ marginTop: "20px" }}>
<button
type="button"
onClick={() => setAttemptsExpanded(!attemptsExpanded)}
style={{
backgroundColor: "#6c757d",
border: "none",
borderRadius: "6px",
color: "white",
cursor: "pointer",
fontSize: "14px",
padding: "8px 16px",
marginBottom: "10px",
display: "flex",
alignItems: "center",
gap: "8px"
}}
>
{attemptsExpanded ? "▼" : "▶"}
View All Attempts ({attempts.length})
</button>
{attemptsExpanded && (
<div
style={{
backgroundColor: "#f8f9fa",
border: "1px solid #dee2e6",
borderRadius: "8px",
padding: "16px",
maxHeight: "400px",
overflowY: "auto"
}}
>
{attempts.map((attempt) => (
<div
key={attempt.slogan}
style={{
backgroundColor: "white",
border: "1px solid #e9ecef",
borderRadius: "6px",
padding: "12px",
marginBottom: "8px",
boxShadow: "0 2px 4px rgba(0,0,0,0.05)"
}}
>
<div
style={{
fontWeight: "bold",
color: "#495057",
marginBottom: "4px"
}}
>
Slogan: {attempt.slogan}
</div>
<div
style={{
color: "#6c757d",
fontSize: "14px",
marginBottom: "4px"
}}
>
Score:{" "}
<span
style={{
fontWeight: "bold",
color:
attempt.score === "pass"
? "#28a745"
: attempt.score === "needs_improvement"
? "#ffc107"
: "#dc3545"
}}
>
{attempt.score}
</span>
</div>
<div
style={{
color: "#6c757d",
fontSize: "14px",
fontStyle: "italic"
}}
>
Feedback: {attempt.feedback}
</div>
</div>
))}
</div>
)}
</div>
)}
</div>
);
}
console.log("[Client] Initializing React app");
const root = createRoot(document.getElementById("root")!);
root.render(<App />);