Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
288 changes: 137 additions & 151 deletions examples/008/images/main/index.html
Original file line number Diff line number Diff line change
@@ -1,163 +1,149 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<style>
body {
margin: 2% 15%;
line-height: 1.8;
overflow-y: scroll;
overflow-x: hidden;
font: 22px "Courier New", Courier, monospace;
padding: 0;
}

main {
max-width: 1080px;
margin: 0 auto;
padding: 3rem 1rem;
}

#plan_execute_container {
display: flex;
justify-content: space-between;
gap: 2rem;
margin-top: 1rem;
}

.monospace-block {
margin-top: 0;
margin-bottom: 0;
box-sizing: border-box;
white-space: pre-wrap;
overflow-wrap: break-word;
line-height: 1.2;
font: inherit;
font-family: monospace;
width: 50%;
min-width: 0;
overflow-wrap: break-word;
word-break: break-word;
}

.plan {
color: darkcyan;
}

.plan li,
.plan ul,
.plan ol,
.plan p {
color: darkcyan;
margin-top: 0;
margin-bottom: 0;
}

.execute li,
.execute ul,
.execute ol,
.execute p {
margin-top: 0;
margin-bottom: 0;
}

textarea {
width: 100%;
max-width: 1080px;
box-sizing: border-box;
border: 1px solid #e9e9e9;
border-radius: 5px;
box-shadow: 2px 2px 10px #f4f4f4;
font-size: inherit;
padding: 1rem;
display: block;
height: calc(3 * 1.8em + 14.8px);
margin-bottom: 10px;
}
</style>
<title></title>
</head>
<body>
<main>
<textarea id="in" autofocus placeholder="How can I help you..."></textarea>
<div id="plan_execute_container">
<div id="plan" class="plan monospace-block"></div>
<div id="execute" class="execute monospace-block"></div>
</div>
<main>

<script>
async function appendCharByChar(text, buffer, element, delay = 5) {
for (const char of text) {
buffer.value += char;
element.innerHTML = marked.parse(buffer.value, {breaks: true});
await new Promise(resolve => {
setTimeout(resolve, delay);
});
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<style>
body {
margin: 2% 15%;
line-height: 1.8;
overflow-y: scroll;
overflow-x: hidden;
font: 22px "Courier New", Courier, monospace;
padding: 0;
}
}

async function processLine(line, planBuffer, executeBuffer) {
if (line.trim()) {
const parsed = JSON.parse(line);
console.info("parsed", parsed);
let phase = parsed.phase;
for (const {content} of parsed.messages) {
if (content) {
if (phase === "planning") {
const plan = document.getElementById("plan");
await appendCharByChar(content, planBuffer, plan);
} else {
const execute = document.getElementById("execute");
await appendCharByChar(content, executeBuffer, execute);
}
}
}

main {
max-width: 1080px;
margin: 0 auto;
padding: 3rem 1rem;
}
}

async function send(message) {
const input = document.getElementById("in");
input.disabled = true;

const plan = document.getElementById("plan");
plan.innerHTML = "";

const execute = document.getElementById("execute");
execute.innerHTML = "";

const response = await fetch("/agents/henry?stream=true&content_size=500&timeout=60", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({message: message}),
});

const decoder = new TextDecoder();
let decodingBuffer = "";
let planBuffer = {value: ""}
let executeBuffer = {value: ""}

for await (const chunk of response.body) {
decodingBuffer += decoder.decode(chunk, {stream: true});
const lines = decodingBuffer.split('\n');
decodingBuffer = lines.pop();
for (const line of lines) await processLine(line, planBuffer, executeBuffer);

.monospace-block {
margin-top: 0;
margin-bottom: 0;
box-sizing: border-box;
white-space: pre-wrap;
overflow-wrap: break-word;
line-height: 1.2;
font: inherit;
font-family: monospace;
}

await processLine(decodingBuffer, executeBuffer);
.plan {
color: darkcyan;
}

input.disabled = false;
input.focus();
}
.plan li,
.plan ul,
.plan ol,
.plan p {
color: darkcyan;
margin-top: 0;
margin-bottom: 0;
}

.execute li,
.execute ul,
.execute ol,
.execute p {
margin-top: 0;
margin-bottom: 0;
}

document.getElementById("in").addEventListener("keydown", async e => {
if (e.key === "Enter" && !e.shiftKey && !e.target.disabled && e.target.value.trim()) {
e.preventDefault();
await send(e.target.value);
textarea {
width: 100%;
max-width: 1080px;
box-sizing: border-box;
border: 1px solid #e9e9e9;
border-radius: 5px;
box-shadow: 2px 2px 10px #f4f4f4;
font-size: inherit;
padding: 1rem;
display: block;
height: calc(3 * 1.8em + 14.8px);
margin-bottom: 10px;
}
});
</script>
</style>
<title></title>
</head>
<body>
<main>
<textarea id="in" autofocus placeholder="How can I help you..."></textarea>
<div id="out" class="monospace-block"></div>
<main>

<script>
let currentPhase = "planning";
let currentElement = document.createElement("div");
currentElement.className = "plan";
let currentBuffer = {"value": ""};

async function appendCharByChar(text, delay = 5) {
for (const char of text) {
currentBuffer.value += char;
currentElement.innerHTML = marked.parse(currentBuffer.value, { breaks: true });
await new Promise(resolve => setTimeout(resolve, delay));
}
}

async function processLine(line) {
if (line.trim()) {
const parsed = JSON.parse(line);
console.info("parsed", parsed);
let phase = parsed.phase;
if (currentPhase !== phase) {
currentPhase = phase;
currentElement = document.createElement("div");
currentElement.className = (phase === "planning") ? "plan" : "execute";
document.getElementById("out").appendChild(currentElement);
currentBuffer = {"value": ""};
}
for (const {content} of parsed.messages) {
if (content) {
await appendCharByChar(content);
}
}
}
}

async function send(message) {
const input = document.getElementById("in");
input.disabled = true;

const out = document.getElementById("out");
out.innerHTML = "";
out.appendChild(currentElement);

const response = await fetch("/agents/henry?stream=true&content_size=500&timeout=600", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({message: message}),
});

const decoder = new TextDecoder();
let decodingBuffer = "";

for await (const chunk of response.body) {
decodingBuffer += decoder.decode(chunk, {stream: true});
const lines = decodingBuffer.split('\n');
decodingBuffer = lines.pop();
for (const line of lines) await processLine(line);
}

await processLine(decodingBuffer);

input.disabled = false;
input.focus();
}

document.getElementById("in").addEventListener("keydown", async e => {
if (e.key === "Enter" && !e.shiftKey && !e.target.disabled && e.target.value.trim()) {
e.preventDefault();
await send(e.target.value);
}
});
</script>
</body>
</html>
Loading
Loading