use lowdb for faster iteration; use strings for ids and camelCase for field names for consistency
This commit is contained in:
@@ -17,13 +17,12 @@ import {
|
||||
import { usePageContext } from "vike-react/usePageContext";
|
||||
import { useData } from "vike-react/useData";
|
||||
import type { Data } from "./+data";
|
||||
import type { ConversationsId } from "../../../database/generated/public/Conversations";
|
||||
import type { CommittedMessage, DraftMessage } from "../../../types";
|
||||
import Markdown from "react-markdown";
|
||||
|
||||
export default function ChatPage() {
|
||||
const pageContext = usePageContext();
|
||||
const conversationId = Number(pageContext.routeParams.id) as ConversationsId;
|
||||
const conversationId = pageContext.routeParams.id;
|
||||
const conversationTitle = useStore(
|
||||
(state) => state.conversations.find((c) => c.id === conversationId)?.title,
|
||||
);
|
||||
@@ -126,7 +125,7 @@ export default function ChatPage() {
|
||||
content: response.insertedAssistantMessage?.content,
|
||||
index: response.insertedAssistantMessage?.index,
|
||||
runningSummary:
|
||||
response.insertedAssistantMessage?.running_summary ||
|
||||
response.insertedAssistantMessage?.runningSummary ||
|
||||
undefined,
|
||||
} as CommittedMessage,
|
||||
];
|
||||
@@ -185,17 +184,18 @@ function Messages({
|
||||
bdrs="md"
|
||||
>
|
||||
<div>
|
||||
{"index" in message ? message.index : ""}
|
||||
{message.role}
|
||||
{"index" in message ? message.index : ""} {message.role}
|
||||
</div>
|
||||
<Markdown>{message.content}</Markdown>
|
||||
{"runningSummary" in message && (
|
||||
</Box>
|
||||
{"runningSummary" in message && (
|
||||
<Box w="75%" bd="dotted" p="md" bdrs="md">
|
||||
<div>
|
||||
<strong>Running Summary:</strong>
|
||||
<Markdown>{message.runningSummary}</Markdown>
|
||||
</div>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
</Group>
|
||||
))}
|
||||
</Stack>
|
||||
|
||||
@@ -7,10 +7,10 @@ export const data = async (pageContext: PageContextServer) => {
|
||||
const { id } = pageContext.routeParams;
|
||||
const caller = createCaller({});
|
||||
const conversation = await caller.fetchConversation({
|
||||
id: Number(id),
|
||||
id,
|
||||
});
|
||||
const messages = await caller.fetchMessages({
|
||||
conversationId: Number(id),
|
||||
conversationId: id,
|
||||
});
|
||||
return { conversation, messages };
|
||||
};
|
||||
|
||||
+53
-66
@@ -17,9 +17,8 @@ import { env } from "../../server/env.js";
|
||||
// ConsistencyLevelEnum,
|
||||
// type NumberArrayId,
|
||||
// } from "@zilliz/milvus2-sdk-node";
|
||||
import { db } from "../../database/postgres";
|
||||
import type { ConversationsId } from "../../database/generated/public/Conversations";
|
||||
import type { UsersId } from "../../database/generated/public/Users";
|
||||
import { db } from "../../database/lowdb";
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
const mainSystemPrompt = ({
|
||||
systemPrompt,
|
||||
@@ -47,75 +46,64 @@ const openrouter = createOpenRouter({
|
||||
|
||||
export const chat = router({
|
||||
listConversations: publicProcedure.query(async () => {
|
||||
const rows = await db.selectFrom("conversations").selectAll().execute();
|
||||
const rows = await db.data.conversations;
|
||||
return rows;
|
||||
}),
|
||||
fetchConversation: publicProcedure
|
||||
.input((x) => x as { id: number })
|
||||
.input((x) => x as { id: string })
|
||||
.query(async ({ input: { id } }) => {
|
||||
const row = await db
|
||||
.selectFrom("conversations")
|
||||
.selectAll()
|
||||
.where("id", "=", id as ConversationsId)
|
||||
.executeTakeFirst();
|
||||
const row = await db.data.conversations.find((c) => c.id === id);
|
||||
return row;
|
||||
}),
|
||||
createConversation: publicProcedure.mutation(async () => {
|
||||
const title = "New Conversation";
|
||||
const row = await db
|
||||
.insertInto("conversations")
|
||||
.values({
|
||||
title,
|
||||
user_id: 1 as UsersId,
|
||||
})
|
||||
.returningAll()
|
||||
.executeTakeFirst();
|
||||
const row = {
|
||||
id: nanoid(),
|
||||
title,
|
||||
userId: "1",
|
||||
};
|
||||
await db.data.conversations.push(row);
|
||||
db.write();
|
||||
return row;
|
||||
}),
|
||||
deleteConversation: publicProcedure
|
||||
.input((x) => x as { id: number })
|
||||
.input((x) => x as { id: string })
|
||||
.mutation(async ({ input: { id } }) => {
|
||||
const result = await db
|
||||
.deleteFrom("conversations")
|
||||
.where("id", "=", Number(id) as ConversationsId)
|
||||
.execute();
|
||||
return result;
|
||||
await db.data.conversations.splice(
|
||||
db.data.conversations.findIndex((c) => c.id === id),
|
||||
1,
|
||||
);
|
||||
db.write();
|
||||
return { ok: true };
|
||||
}),
|
||||
updateConversationTitle: publicProcedure
|
||||
.input(
|
||||
(x) =>
|
||||
x as {
|
||||
id: number;
|
||||
id: string;
|
||||
title: string;
|
||||
},
|
||||
)
|
||||
.mutation(async ({ input: { id, title } }) => {
|
||||
const result = await db
|
||||
.updateTable("conversations")
|
||||
.set({ title })
|
||||
.where("id", "=", Number(id) as ConversationsId)
|
||||
.execute();
|
||||
return result[0];
|
||||
const conversation = await db.data.conversations.find((c) => c.id === id);
|
||||
if (!conversation) throw new Error("Conversation not found");
|
||||
conversation.title = title;
|
||||
db.write();
|
||||
return { ok: true };
|
||||
}),
|
||||
fetchMessages: publicProcedure
|
||||
.input((x) => x as { conversationId: number })
|
||||
.input((x) => x as { conversationId: string })
|
||||
.query(async ({ input: { conversationId } }) => {
|
||||
const rows = await db
|
||||
.selectFrom("messages")
|
||||
.selectAll()
|
||||
.where("conversation_id", "=", conversationId as ConversationsId)
|
||||
.execute();
|
||||
return rows.map((row) => ({
|
||||
...row,
|
||||
conversationId: conversationId as ConversationsId,
|
||||
runningSummary: row.running_summary,
|
||||
})) as Array<CommittedMessage>;
|
||||
const rows = await db.data.messages.filter(
|
||||
(m) => m.conversationId === conversationId,
|
||||
);
|
||||
return rows as Array<CommittedMessage>;
|
||||
}),
|
||||
sendMessage: publicProcedure
|
||||
.input(
|
||||
(x) =>
|
||||
x as {
|
||||
conversationId: number;
|
||||
conversationId: string;
|
||||
messages: Array<DraftMessage | CommittedMessage>;
|
||||
systemPrompt: string;
|
||||
parameters: OtherParameters;
|
||||
@@ -140,17 +128,17 @@ export const chat = router({
|
||||
.runningSummary as string)
|
||||
: "";
|
||||
/** Save the incoming message to the database. */
|
||||
const insertedUserMessage = await db
|
||||
.insertInto("messages")
|
||||
.values({
|
||||
conversation_id: conversationId as ConversationsId,
|
||||
content: messages[messages.length - 1].content,
|
||||
role: "user" as const,
|
||||
index: messages.length - 1,
|
||||
created_at: new Date().toISOString(),
|
||||
})
|
||||
.returning(["id", "index"])
|
||||
.executeTakeFirst();
|
||||
const insertedUserMessage: CommittedMessage = {
|
||||
id: nanoid(),
|
||||
conversationId,
|
||||
content: messages[messages.length - 1].content,
|
||||
role: "user" as const,
|
||||
index: messages.length - 1,
|
||||
createdAt: new Date().toISOString(),
|
||||
};
|
||||
await db.data.messages.push(insertedUserMessage);
|
||||
// do not db.write() until the end
|
||||
|
||||
/** Generate a new message from the model, but hold-off on adding it to
|
||||
* the database until we produce the associated running-summary, below.
|
||||
* The model should be given the conversation summary thus far, and of
|
||||
@@ -249,18 +237,17 @@ export const chat = router({
|
||||
tools: undefined,
|
||||
...parameters,
|
||||
});
|
||||
const insertedAssistantMessage = await db
|
||||
.insertInto("messages")
|
||||
.values({
|
||||
conversation_id: conversationId as ConversationsId,
|
||||
content: mainResponse.text,
|
||||
running_summary: runningSummaryResponse.text,
|
||||
role: "assistant" as const,
|
||||
index: messages.length,
|
||||
created_at: new Date().toISOString(),
|
||||
})
|
||||
.returningAll()
|
||||
.executeTakeFirst();
|
||||
const insertedAssistantMessage: CommittedMessage = {
|
||||
id: nanoid(),
|
||||
conversationId,
|
||||
content: mainResponse.text,
|
||||
runningSummary: runningSummaryResponse.text,
|
||||
role: "assistant" as const,
|
||||
index: messages.length,
|
||||
createdAt: new Date().toISOString(),
|
||||
};
|
||||
await db.data.messages.push(insertedAssistantMessage);
|
||||
await db.write();
|
||||
/** TODO: notify the caller, somehow, that some messages were saved to
|
||||
* the database and/or were outfitted with runningSummaries, so the
|
||||
* caller can update its UI state. */
|
||||
|
||||
Reference in New Issue
Block a user