send and display the conversation name

This commit is contained in:
Charlotte Som 2025-02-26 10:21:15 +00:00
parent 43017bca36
commit e45fde5178
4 changed files with 62 additions and 4 deletions

View file

@ -1,3 +1,5 @@
import { Signal } from "@char/aftercare";
const main = document.querySelector("main")!;
async function nav() {
@ -9,7 +11,7 @@ async function nav() {
button.addEventListener("click", e => {
e.preventDefault();
main.append(conversationUI(conversation.id));
main.append(conversationUI(conversation.id, conversation.name));
nav.remove();
});
@ -22,7 +24,7 @@ async function nav() {
_tap={b =>
b.addEventListener("click", e => {
e.preventDefault();
main.append(conversationUI("new"));
main.append(conversationUI("new", "New conversation"));
nav.remove();
})
}
@ -37,7 +39,37 @@ async function nav() {
function conversationUI(id: string) {
window.location.hash = `#${id}`;
const socket = new WebSocket(`/api/conversation/${id}/connect`);
let socket: WebSocket;
let connected = false;
const connect = () => {
socket = new WebSocket(
`/api/conversation/${id}/connect` + (connected ? "?continue=1" : ""),
);
socket.addEventListener("open", () => (connected = true));
socket.addEventListener("close", () => (socket = connect()));
socket.addEventListener("error", ev => {
console.warn(ev);
// TODO: handle errors
});
return socket;
};
socket = connect();
const header = (
<header>
<h1 />
<button tabIndex={-1} type="button" className="danger">
delete
</button>
</header>
);
const name = new Signal("");
name.subscribeImmediate(it => (header.querySelector("h1")!.textContent = it));
header.querySelector("button")!.addEventListener("click", async e => {
e.preventDefault();
await fetch(`/api/conversation/${id}`, { method: "DELETE" });
window.location.hash = "";
});
const chatlog = <section className="chatlog" />;
const inFlightMessages = new Map<string, Element>();
@ -64,6 +96,8 @@ function conversationUI(id: string) {
article.append(message.c);
} else if ("d" in message) {
inFlightMessages.delete(message.d);
} else if ("n" in message) {
name.set(message.n);
}
if (scrolledToBottom) chatlog.scrollTop = chatlog.scrollHeight - chatlog.clientHeight;
@ -83,6 +117,7 @@ function conversationUI(id: string) {
return (
<section className="conversation">
{header}
{chatlog}
{form}
</section>

View file

@ -51,6 +51,19 @@ main,
}
}
.conversation header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
font-size: smaller;
gap: 1em;
* {
margin: 0;
}
}
.chatlog {
flex: 1;

View file

@ -1,5 +1,5 @@
from server.http import Starlette, Route, Request, Response, JSONResponse, WebSocketRoute, Mount
from server.inference import list_conversations, connect_to_conversation
from server.inference import list_conversations, delete_conversation, connect_to_conversation
from starlette.staticfiles import StaticFiles
async def status(request: Request) -> Response:
@ -8,6 +8,7 @@ async def status(request: Request) -> Response:
app = Starlette(debug=True, routes=[
Route("/api/", status),
Route("/api/conversation", list_conversations, methods=["GET"]),
Route("/api/conversation/{conversation}", delete_conversation, methods=["DELETE"]),
WebSocketRoute("/api/conversation/{conversation}/connect", connect_to_conversation),
Mount("/", app=StaticFiles(directory="client/web", html=True), name="client")
])

View file

@ -14,6 +14,13 @@ async def list_conversations(request: Request):
return JSONResponse(conversations)
async def delete_conversation(request: Request):
conversation_id = request.path_params["conversation"]
db["responses"].delete_where("conversation_id = ?", [conversation_id])
db["conversations"].delete(conversation_id)
return JSONResponse({"status": "ok"})
async def connect_to_conversation(ws: WebSocket):
continuing = bool(ws.query_params.get("continue"))
conversation_id = ws.path_params["conversation"]
@ -42,6 +49,8 @@ async def connect_to_conversation(ws: WebSocket):
await ws.send_text(json({"u": response.prompt.prompt})) # user
await ws.send_text(json({"f": response.text_or_raise()})) # full
await ws.send_text(json({"n": conversation.name}))
if conversation_id == "new":
await ws.send_text(json({"i": conversation.id}))