transition to postgresql for persistence layer

This commit is contained in:
Avraham Sakal
2025-08-31 12:04:18 -04:00
parent d827412feb
commit f4e9c62e96
21 changed files with 511 additions and 213 deletions
+8 -9
View File
@@ -3,29 +3,28 @@ import {
publicProcedure,
createCallerFactory,
} from "../../trpc/server";
import { _db } from "../../database/lowdb";
import { db } from "../../database/index";
export const conversations = router({
fetchAll: publicProcedure.query(async () => {
return await _db.conversations.findAll();
return await db.conversations.findAll();
}),
fetchOne: publicProcedure
.input((x) => x as { id: string })
.query(async ({ input: { id } }) => {
return await _db.conversations.findById(id);
return await db.conversations.findById(id);
}),
start: publicProcedure.mutation(async () => {
const row = {
id: "",
title: "New Conversation",
userId: "1",
userId: "019900bb-61b3-7333-b760-b27784dfe33b",
};
return await _db.conversations.create(row);
return await db.conversations.create(row);
}),
deleteOne: publicProcedure
.input((x) => x as { id: string })
.mutation(async ({ input: { id } }) => {
await _db.conversations.delete(id);
await db.conversations.delete(id);
return { ok: true };
}),
updateTitle: publicProcedure
@@ -37,13 +36,13 @@ export const conversations = router({
}
)
.mutation(async ({ input: { id, title } }) => {
await _db.conversations.update(id, { title });
await db.conversations.update(id, { title });
return { ok: true };
}),
fetchMessages: publicProcedure
.input((x) => x as { conversationId: string })
.query(async ({ input: { conversationId } }) => {
return await _db.conversations.fetchMessages(conversationId);
return await db.conversations.fetchMessages(conversationId);
}),
});
+5 -4
View File
@@ -3,10 +3,11 @@ import {
publicProcedure,
createCallerFactory,
} from "../../trpc/server.js";
import { _db, type Fact } from "../../database/lowdb.js";
import { db } from "../../database/index.js";
import type { DraftMessage } from "../../types.js";
import { openrouter, MODEL_NAME } from "./provider.js";
import { generateObject, generateText, jsonSchema } from "ai";
import type { Fact } from "../../database/common.js";
const factTriggersSystemPrompt = ({
previousRunningSummary,
@@ -61,7 +62,7 @@ export const factTriggers = router({
fetchByFactId: publicProcedure
.input((x) => x as { factId: string })
.query(async ({ input: { factId } }) => {
return _db.factTriggers.findByFactId(factId);
return db.factTriggers.findByFactId(factId);
}),
deleteOne: publicProcedure
.input(
@@ -71,7 +72,7 @@ export const factTriggers = router({
}
)
.mutation(async ({ input: { factTriggerId } }) => {
await _db.factTriggers.delete(factTriggerId);
await db.factTriggers.delete(factTriggerId);
return { ok: true };
}),
update: publicProcedure
@@ -83,7 +84,7 @@ export const factTriggers = router({
}
)
.mutation(async ({ input: { factTriggerId, content } }) => {
_db.factTriggers.update(factTriggerId, { content });
db.factTriggers.update(factTriggerId, { content });
return { ok: true };
}),
generateFromFact: publicProcedure
+4 -4
View File
@@ -3,7 +3,7 @@ import {
publicProcedure,
createCallerFactory,
} from "../../trpc/server.js";
import { _db } from "../../database/lowdb.js";
import { db } from "../../database/index.js";
import type { DraftMessage } from "../../types.js";
import { MODEL_NAME, openrouter } from "./provider.js";
import { generateObject, generateText, jsonSchema } from "ai";
@@ -57,7 +57,7 @@ export const facts = router({
fetchByConversationId: publicProcedure
.input((x) => x as { conversationId: string })
.query(async ({ input: { conversationId } }) => {
return await _db.facts.findByConversationId(conversationId);
return await db.facts.findByConversationId(conversationId);
}),
deleteOne: publicProcedure
.input(
@@ -67,7 +67,7 @@ export const facts = router({
}
)
.mutation(async ({ input: { factId } }) => {
await _db.facts.delete(factId);
await db.facts.delete(factId);
return { ok: true };
}),
update: publicProcedure
@@ -79,7 +79,7 @@ export const facts = router({
}
)
.mutation(async ({ input: { factId, content } }) => {
await _db.facts.update(factId, { content });
await db.facts.update(factId, { content });
return { ok: true };
}),
extractFromNewMessages: publicProcedure
+2 -2
View File
@@ -6,7 +6,7 @@ import {
import { MODEL_NAME, openrouter } from "./provider.js";
import { generateObject, generateText, jsonSchema } from "ai";
import type { DraftMessage } from "../../types.js";
import { _db } from "../../database/lowdb";
import { db } from "../../database/index";
const runningSummarySystemPrompt = ({
previousRunningSummary,
@@ -52,7 +52,7 @@ export const messages = router({
fetchByConversationId: publicProcedure
.input((x) => x as { conversationId: string })
.query(async ({ input: { conversationId } }) => {
return await _db.messages.findByConversationId(conversationId);
return await db.messages.findByConversationId(conversationId);
}),
generateRunningSummary: publicProcedure
.input(
+2 -2
View File
@@ -5,5 +5,5 @@ export const openrouter = createOpenRouter({
});
// export const MODEL_NAME = "mistralai/mistral-nemo";
// export const MODEL_NAME = "openai/gpt-oss-20b";
export const MODEL_NAME = "openai/gpt-5-mini";
export const MODEL_NAME = "openai/gpt-oss-20b";
// export const MODEL_NAME = "openai/gpt-5-mini";
+17 -25
View File
@@ -14,8 +14,7 @@ import type {
// ConsistencyLevelEnum,
// type NumberArrayId,
// } from "@zilliz/milvus2-sdk-node";
import { db, type FactTrigger, type Fact, _db } from "../../database/lowdb.js";
import { nanoid } from "nanoid";
import { db } from "../../database/index.js";
import { conversations } from "./conversations.js";
import { messages } from "./messages.js";
import { facts, createCaller as createCallerFacts } from "./facts.js";
@@ -23,6 +22,7 @@ import { createCaller as createCallerMessages } from "./messages.js";
import { createCaller as createCallerFactTriggers } from "./fact-triggers.js";
import { factTriggers } from "./fact-triggers.js";
import { MODEL_NAME, openrouter } from "./provider.js";
import type { Fact, FactTrigger } from "../../database/common.js";
const factsCaller = createCallerFacts({});
const messagesCaller = createCallerMessages({});
@@ -96,16 +96,14 @@ export const chat = router({
previousRunningSummaryIndex + 1
);
/** Save the incoming message to the database. */
const insertedUserMessage: CommittedMessage = {
id: nanoid(),
const insertedUserMessage = await db.messages.create({
conversationId,
// content: messages[messages.length - 1].content,
// role: "user" as const,
...messages[messages.length - 1],
index: messages.length - 1,
createdAt: new Date().toISOString(),
};
await _db.messages.create(insertedUserMessage);
});
/** Generate a new message from the model, but hold-off on adding it to
* the database until we produce the associated running-summary, below.
@@ -154,15 +152,13 @@ export const chat = router({
messagesSincePreviousRunningSummary: [],
newMessages: messagesSincePreviousRunningSummary,
});
const insertedFactsFromUserMessage: Array<Fact> =
const insertedFactsFromUserMessage = await db.facts.createMany(
factsFromUserMessageResponse.object.facts.map((fact) => ({
id: nanoid(),
userId: "1",
userId: "019900bb-61b3-7333-b760-b27784dfe33b",
sourceMessageId: insertedUserMessage.id,
content: fact,
createdAt: new Date().toISOString(),
}));
_db.facts.createMany(insertedFactsFromUserMessage);
}))
);
/** Produce a running summary of the conversation, and save that along
* with the model's response to the database. The new running summary is
@@ -174,8 +170,7 @@ export const chat = router({
mainResponseContent: mainResponse.text,
previousRunningSummary,
});
const insertedAssistantMessage: CommittedMessage = {
id: nanoid(),
const insertedAssistantMessage = await db.messages.create({
conversationId,
// content: mainResponse.text,
parts: [{ type: "text", text: mainResponse.text }],
@@ -183,8 +178,7 @@ export const chat = router({
role: "assistant" as const,
index: messages.length,
createdAt: new Date().toISOString(),
};
await _db.messages.create(insertedAssistantMessage);
});
/** Extract Facts from the model's response, and add them to the database,
* linking the Facts with the messages they came from. */
const factsFromAssistantMessageResponse =
@@ -200,15 +194,14 @@ export const chat = router({
],
});
const insertedFactsFromAssistantMessage: Array<Fact> =
const insertedFactsFromAssistantMessage = await db.facts.createMany(
factsFromAssistantMessageResponse.object.facts.map((factContent) => ({
id: nanoid(),
userId: "1",
userId: "019900bb-61b3-7333-b760-b27784dfe33b",
sourceMessageId: insertedAssistantMessage.id,
content: factContent,
createdAt: new Date().toISOString(),
}));
_db.facts.createMany(insertedFactsFromAssistantMessage);
}))
);
const insertedFacts = [
...insertedFactsFromUserMessage,
@@ -227,9 +220,8 @@ export const chat = router({
messagesSincePreviousRunningSummary,
fact,
});
const insertedFactTriggers: Array<FactTrigger> =
const insertedFactTriggers: Array<Omit<FactTrigger, "id">> =
factTriggers.object.factTriggers.map((factTrigger) => ({
id: nanoid(),
sourceFactId: fact.id,
content: factTrigger,
priorityMultiplier: 1,
@@ -237,10 +229,10 @@ export const chat = router({
scopeConversationId: conversationId,
createdAt: new Date().toISOString(),
}));
_db.factTriggers.createMany(insertedFactTriggers);
db.factTriggers.createMany(insertedFactTriggers);
}
await db.write();
// await db.write();
return {
insertedAssistantMessage,