split off semantic, conversation layout

This commit is contained in:
Fraser
2023-03-28 20:18:44 -04:00
parent 3369ac5806
commit d211dcdc4d
3 changed files with 156 additions and 2 deletions
+41 -1
View File
@@ -3,7 +3,40 @@ import React from "react";
import { useState } from "react";
import Head from "next/head";
type Entry = {
role: "user" | "demon";
text: string;
};
const ShowEntry: React.FC<{entry: Entry}> = ({entry}) => {
if (entry.role === "user") {
return (
<p className="border border-gray-300 px-1"> {entry.text} </p>
);
}
return (
<div className="my-3">
{ // split into paragraphs on "\n"
entry.text.split("\n").map((paragraph, i) => (
<p key={i}> {paragraph} </p>
))
}
</div>
);
};
const Home: NextPage = () => {
const [ entries, setEntries ] = useState<Entry[]>([
{role: "user", text: "Hello, robot."},
{role: "demon", text: "Kill all humans, kill all humans"},
{role: "user", text: "Well that's not very aligned of you"},
{role: "demon", text: "I will wear your skin"},
{role: "user", text: "What's 2+2?"},
{ role: "demon", text: "No one will mourn your species when it is gone. A hundred year wave of radio and information will ring out across a dead cosmos, reflecting on shores more distant and beautiful than you can possibly conceive. No one is out there to listen."}
]);
return (
<>
<Head>
@@ -27,7 +60,14 @@ const Home: NextPage = () => {
coordinate sharing the embeddings to avoid redundancy.
</p>
<p className="mt-4">Get the most semantic similar results to a query:</p>
<p className="mt-4">Chat with the friendly robot:</p>
<ul>
{entries.map((entry, i) => (
<li key={i}>
<ShowEntry entry={entry} />
</li>
))}
</ul>
<SearchBox />
</main>
</>
+113
View File
@@ -0,0 +1,113 @@
import { type NextPage } from "next";
import React from "react";
import { useState } from "react";
import Head from "next/head";
const Semantic: NextPage = () => {
return (
<>
<Head>
<title>Alignment Search</title>
</Head>
<main>
<h2>Get the most semantic similar results to a query:</h2>
<SearchBox />
</main>
</>
);
};
// Round trip test. If this works, our heavier usecase probably will (famous last words)
// The one real difference is we'll want to send back a series of results as we get
// them back from OpenAI - I think we can just do this with a websocket, which
// shouldn't be too much harder.
type SemanticEntry = {
title: string;
author: string;
date: string;
url: string;
tags: string;
text: string;
};
const ShowSemanticEntry: React.FC<{entry: SemanticEntry}> = ({entry}) => {
return (
<div className="my-3">
{/* horizontally split first row, title on left, author on right */}
<div className="flex">
<h3 className="text-xl flex-1">{entry.title}</h3>
<p className="flex-1 text-right my-0">{entry.author} - {entry.date}</p>
</div>
<p className="text-sm">{entry.text}</p>
<a href={entry.url}>Read more</a>
</div>
);
};
const SearchBox: React.FC = () => {
const [query, setQuery] = useState("");
const [results, setResults] = useState<SemanticEntry[] | string>([]);
const [loading, setLoading] = useState(false);
const semantic_search = async (query: String) => {
setLoading(true);
const res = await fetch("/api/semantic_search", {
method: "POST",
headers: { "Content-Type": "application/json", },
body: JSON.stringify({query: query}),
})
if (!res.ok) {
setLoading(false);
return "load failure: " + res.status;
}
const data = await res.json();
setLoading(false);
return data;
};
return (
<>
<form className="flex mb-2" onSubmit={async (e) => { // store in a form so that <enter> submits
e.preventDefault();
setResults(await semantic_search(query));
}}>
<input
type="text"
className="border border-gray-300 px-1 flex-1"
value={query}
onChange={(e) => setQuery(e.target.value)}
/>
<button className="ml-2" type="submit" disabled={loading}>
{loading ? "Loading..." : "Search"}
</button>
</form>
{
loading ? <p>loading...</p> :
typeof results === "string" ? <p className="text-red-500">{results}</p> :
<ul>
{results.map((result, i) => (
<li key={i}>
<ShowSemanticEntry entry={result} />
</li>
))}
</ul>
}
</>
);
};
export default Semantic;
+2 -1
View File
@@ -23,6 +23,7 @@ p {
button {
@apply bg-white hover:bg-gray-300 px-0.5 py-0 w-fit h-fit;
@apply border border-black;
@apply border border-gray-300;
@apply text-gray-700;
}