Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/** @jsxImportSource https://esm.sh/react */
import React, { useState, useEffect, useRef } from "https://esm.sh/react";
import { createRoot } from "https://esm.sh/react-dom/client";
import Cerebras from "https://esm.sh/@cerebras/cerebras_cloud_sdk";
const MODELS = ["llama3.1-8b", "llama3.1-70b"];
function App() {
const [messages, setMessages] = useState<Array<{ role: string; content: string }>>([]);
const [edits, setEdits] = useState<Array<{ id: number; content: string }>>(
[]
);
const [input, setInput] = useState("");
const [isLoading, setIsLoading] = useState(false);
const [htmlOutput, setHtmlOutput] = useState("");
const [selectedModel, setSelectedModel] = useState(MODELS[0]);
const messagesEndRef = useRef<HTMLDivElement>(null);
const iframeRef = useRef<HTMLIFrameElement>(null);
useEffect(() => {
if (iframeRef.current) {
const iframeDoc = iframeRef.current.contentDocument;
iframeDoc?.open();
iframeDoc?.write(htmlOutput);
iframeDoc?.close();
}
}, [htmlOutput]);
const sendMessage = async (e?: React.FormEvent) => {
e?.preventDefault();
if (input.trim() === "") return;
const newMessages = [
{ role: "system", content: "You are a helpful assistant. Respond only with HTML code wrapped in ```html ``` code fences. The HTML should be a complete, valid document including <!DOCTYPE html>, <html>, <head>, and <body> tags." },
...messages,
{ role: "user", content: input }
];
setMessages(newMessages);
setInput("");
setIsLoading(true);
try {
const response = await fetch("/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ messages: newMessages, model: selectedModel }),
});
const data = await response.json();
// Parse out the HTML content
const htmlMatch = data.content.match(/```html\s*([\s\S]*?)\s*```/);
if (htmlMatch && htmlMatch[1]) {
setHtmlOutput(htmlMatch[1].trim());
} else {
setHtmlOutput("<p>No valid HTML found in the response.</p>");
}
setMessages([...newMessages, { role: "assistant", content: data.content }]);
if (input.trim() !== "") {
setEdits([...edits, { id: Date.now(), content: input }]);
}
} catch (error) {
console.error("Error:", error);
} finally {
setIsLoading(false);
}
};
return (
<div className="flex h-screen">
<div className="w-1/2 p-4 flex flex-col">
<h1 className="text-2xl font-bold mb-4">HTML Editor with Llama 8B/70B</h1>
<select
value={selectedModel}
onChange={(e) => setSelectedModel(e.target.value)}
className="mb-4 p-2 border border-gray-300 rounded-lg"
>
{MODELS.map((model) => <option key={model} value={model}>{model}</option>)}
</select>
<div className="bg-gray-100 p-4 rounded-lg mb-4 flex-grow overflow-y-auto">
{edits.map((edit) => (
<div
key={edit.id}
className="mb-2 p-2 rounded-lg bg-blue-200 text-5xl font-medium"
>
{edit.content}
</div>
))}
<div ref={messagesEndRef} />
{isLoading && (
<div className="text-center text-gray-500">AI is thinking...</div>
)}
<div ref={messagesEndRef} />
</div>
<form onSubmit={sendMessage} className="flex">
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
className="flex-grow border border-gray-300 rounded-l-lg p-2 font-mono text-5xl"
placeholder="Type your message..."
/>
stevekrouse-chatwithcerebras.web.val.run
September 5, 2024