refactor trpc procedures into domains
This commit is contained in:
@@ -40,7 +40,7 @@ export default function LayoutDefault({
|
|||||||
const conversationId = useStore((state) => state.selectedConversationId);
|
const conversationId = useStore((state) => state.selectedConversationId);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
trpc.chat.listConversations.query().then((res) => {
|
trpc.chat.conversations.fetchAll.query().then((res) => {
|
||||||
setConversations(res);
|
setConversations(res);
|
||||||
});
|
});
|
||||||
}, [setConversations]);
|
}, [setConversations]);
|
||||||
@@ -55,8 +55,8 @@ export default function LayoutDefault({
|
|||||||
|
|
||||||
async function handleDeleteConversation(conversationId: string) {
|
async function handleDeleteConversation(conversationId: string) {
|
||||||
removeConversation(conversationId);
|
removeConversation(conversationId);
|
||||||
await trpc.chat.deleteConversation.mutate({ id: conversationId });
|
await trpc.chat.conversations.deleteOne.mutate({ id: conversationId });
|
||||||
const res = await trpc.chat.createConversation.mutate();
|
const res = await trpc.chat.conversations.start.mutate();
|
||||||
if (!res?.id) return;
|
if (!res?.id) return;
|
||||||
addConversation(res);
|
addConversation(res);
|
||||||
await navigate(`/chat/${res.id}`);
|
await navigate(`/chat/${res.id}`);
|
||||||
@@ -108,7 +108,7 @@ export default function LayoutDefault({
|
|||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
trpc.chat.createConversation.mutate().then((res) => {
|
trpc.chat.conversations.start.mutate().then((res) => {
|
||||||
if (!res?.id) return;
|
if (!res?.id) return;
|
||||||
addConversation(res);
|
addConversation(res);
|
||||||
navigate(`/chat/${res.id}`);
|
navigate(`/chat/${res.id}`);
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export default function ChatPage() {
|
|||||||
|
|
||||||
async function handleDeleteFact(factId: string) {
|
async function handleDeleteFact(factId: string) {
|
||||||
removeFact(factId);
|
removeFact(factId);
|
||||||
await trpc.chat.deleteFact.mutate({ factId });
|
await trpc.chat.facts.deleteOne.mutate({ factId });
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -90,7 +90,7 @@ export default function ChatPage() {
|
|||||||
setConversationTitle(e.target.value);
|
setConversationTitle(e.target.value);
|
||||||
}}
|
}}
|
||||||
onBlur={(e) => {
|
onBlur={(e) => {
|
||||||
trpc.chat.updateConversationTitle.mutate({
|
trpc.chat.conversations.updateTitle.mutate({
|
||||||
id: conversationId,
|
id: conversationId,
|
||||||
title: e.target.value,
|
title: e.target.value,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ export type Data = Awaited<ReturnType<typeof data>>;
|
|||||||
export const data = async (pageContext: PageContextServer) => {
|
export const data = async (pageContext: PageContextServer) => {
|
||||||
const { id } = pageContext.routeParams;
|
const { id } = pageContext.routeParams;
|
||||||
const caller = createCaller({});
|
const caller = createCaller({});
|
||||||
const conversation = await caller.fetchConversation({
|
const conversation = await caller.conversations.fetchOne({
|
||||||
id,
|
id,
|
||||||
});
|
});
|
||||||
const messages = await caller.fetchMessages({
|
const messages = await caller.conversations.fetchMessages({
|
||||||
conversationId: id,
|
conversationId: id,
|
||||||
});
|
});
|
||||||
const facts = await caller.fetchFacts({
|
const facts = await caller.facts.fetchByConversationId({
|
||||||
conversationId: id,
|
conversationId: id,
|
||||||
});
|
});
|
||||||
return { conversation, messages, facts };
|
return { conversation, messages, facts };
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import {
|
||||||
|
router,
|
||||||
|
publicProcedure,
|
||||||
|
createCallerFactory,
|
||||||
|
} from "../../trpc/server";
|
||||||
|
import type { CommittedMessage } from "../../types.js";
|
||||||
|
import { db } from "../../database/lowdb";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
|
||||||
|
export const conversations = router({
|
||||||
|
fetchAll: publicProcedure.query(async () => {
|
||||||
|
const rows = await db.data.conversations;
|
||||||
|
return rows;
|
||||||
|
}),
|
||||||
|
fetchOne: publicProcedure
|
||||||
|
.input((x) => x as { id: string })
|
||||||
|
.query(async ({ input: { id } }) => {
|
||||||
|
const row = await db.data.conversations.find((c) => c.id === id);
|
||||||
|
return row;
|
||||||
|
}),
|
||||||
|
start: publicProcedure.mutation(async () => {
|
||||||
|
const title = "New Conversation";
|
||||||
|
const row = {
|
||||||
|
id: nanoid(),
|
||||||
|
title,
|
||||||
|
userId: "1",
|
||||||
|
};
|
||||||
|
await db.data.conversations.push(row);
|
||||||
|
db.write();
|
||||||
|
return row;
|
||||||
|
}),
|
||||||
|
deleteOne: publicProcedure
|
||||||
|
.input((x) => x as { id: string })
|
||||||
|
.mutation(async ({ input: { id } }) => {
|
||||||
|
db.data.conversations.splice(
|
||||||
|
db.data.conversations.findIndex((c) => c.id === id),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
const deletedMessageIds = db.data.messages
|
||||||
|
.filter((m) => m.conversationId === id)
|
||||||
|
.map((m) => m.id);
|
||||||
|
db.data.messages = db.data.messages.filter(
|
||||||
|
(m) => m.conversationId !== id,
|
||||||
|
);
|
||||||
|
db.data.facts = db.data.facts.filter(
|
||||||
|
(fact) => !deletedMessageIds.includes(fact.sourceMessageId),
|
||||||
|
);
|
||||||
|
db.write();
|
||||||
|
return { ok: true };
|
||||||
|
}),
|
||||||
|
updateTitle: publicProcedure
|
||||||
|
.input(
|
||||||
|
(x) =>
|
||||||
|
x as {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.mutation(async ({ input: { id, title } }) => {
|
||||||
|
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: string })
|
||||||
|
.query(async ({ input: { conversationId } }) => {
|
||||||
|
const rows = await db.data.messages.filter(
|
||||||
|
(m) => m.conversationId === conversationId,
|
||||||
|
);
|
||||||
|
return rows as Array<CommittedMessage>;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const createCaller = createCallerFactory(conversations);
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import {
|
||||||
|
router,
|
||||||
|
publicProcedure,
|
||||||
|
createCallerFactory,
|
||||||
|
} from "../../trpc/server.js";
|
||||||
|
import { db, type Fact } from "../../database/lowdb.js";
|
||||||
|
|
||||||
|
export const facts = router({
|
||||||
|
fetchByConversationId: publicProcedure
|
||||||
|
.input((x) => x as { conversationId: string })
|
||||||
|
.query(async ({ input: { conversationId } }) => {
|
||||||
|
const conversationMessageIds = db.data.messages
|
||||||
|
.filter((m) => m.conversationId === conversationId)
|
||||||
|
.map((m) => m.id);
|
||||||
|
const rows = await db.data.facts.filter((f) =>
|
||||||
|
conversationMessageIds.includes(f.sourceMessageId),
|
||||||
|
);
|
||||||
|
return rows as Array<Fact>;
|
||||||
|
}),
|
||||||
|
deleteOne: publicProcedure
|
||||||
|
.input(
|
||||||
|
(x) =>
|
||||||
|
x as {
|
||||||
|
factId: string;
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.mutation(async ({ input: { factId } }) => {
|
||||||
|
const deletedFact = db.data.facts.find((fact) => fact.id === factId);
|
||||||
|
if (!deletedFact) throw new Error("Fact not found");
|
||||||
|
db.data.facts.splice(
|
||||||
|
db.data.facts.findIndex((fact) => fact.id === factId),
|
||||||
|
1,
|
||||||
|
);
|
||||||
|
db.write();
|
||||||
|
return { ok: true };
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const createCaller = createCallerFactory(facts);
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import {
|
||||||
|
router,
|
||||||
|
publicProcedure,
|
||||||
|
createCallerFactory,
|
||||||
|
} from "../../trpc/server";
|
||||||
|
import { createCaller as createConversationsCaller } from "./conversations.js";
|
||||||
|
|
||||||
|
export const messages = router({
|
||||||
|
fetchByConversationId: publicProcedure
|
||||||
|
.input((x) => x as { conversationId: string })
|
||||||
|
.query(async ({ input: { conversationId } }) => {
|
||||||
|
const caller = createConversationsCaller({});
|
||||||
|
return await caller.fetchMessages({
|
||||||
|
conversationId,
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const createCaller = createCallerFactory(messages);
|
||||||
+8
-93
@@ -2,7 +2,7 @@ import {
|
|||||||
router,
|
router,
|
||||||
publicProcedure,
|
publicProcedure,
|
||||||
createCallerFactory,
|
createCallerFactory,
|
||||||
} from "../../trpc/server";
|
} from "../../trpc/server.js";
|
||||||
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
import { createOpenRouter } from "@openrouter/ai-sdk-provider";
|
||||||
import { generateObject, generateText, jsonSchema } from "ai";
|
import { generateObject, generateText, jsonSchema } from "ai";
|
||||||
import type { Message as UIMessage } from "ai";
|
import type { Message as UIMessage } from "ai";
|
||||||
@@ -17,8 +17,11 @@ import { env } from "../../server/env.js";
|
|||||||
// ConsistencyLevelEnum,
|
// ConsistencyLevelEnum,
|
||||||
// type NumberArrayId,
|
// type NumberArrayId,
|
||||||
// } from "@zilliz/milvus2-sdk-node";
|
// } from "@zilliz/milvus2-sdk-node";
|
||||||
import { db, type Fact } from "../../database/lowdb";
|
import { db, type Fact } from "../../database/lowdb.js";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
|
import { conversations } from "./conversations.js";
|
||||||
|
import { messages } from "./messages.js";
|
||||||
|
import { facts } from "./facts.js";
|
||||||
|
|
||||||
const mainSystemPrompt = ({
|
const mainSystemPrompt = ({
|
||||||
systemPrompt,
|
systemPrompt,
|
||||||
@@ -111,69 +114,9 @@ const openrouter = createOpenRouter({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const chat = router({
|
export const chat = router({
|
||||||
listConversations: publicProcedure.query(async () => {
|
conversations,
|
||||||
const rows = await db.data.conversations;
|
messages,
|
||||||
return rows;
|
facts,
|
||||||
}),
|
|
||||||
fetchConversation: publicProcedure
|
|
||||||
.input((x) => x as { id: string })
|
|
||||||
.query(async ({ input: { id } }) => {
|
|
||||||
const row = await db.data.conversations.find((c) => c.id === id);
|
|
||||||
return row;
|
|
||||||
}),
|
|
||||||
createConversation: publicProcedure.mutation(async () => {
|
|
||||||
const title = "New Conversation";
|
|
||||||
const row = {
|
|
||||||
id: nanoid(),
|
|
||||||
title,
|
|
||||||
userId: "1",
|
|
||||||
};
|
|
||||||
await db.data.conversations.push(row);
|
|
||||||
db.write();
|
|
||||||
return row;
|
|
||||||
}),
|
|
||||||
deleteConversation: publicProcedure
|
|
||||||
.input((x) => x as { id: string })
|
|
||||||
.mutation(async ({ input: { id } }) => {
|
|
||||||
db.data.conversations.splice(
|
|
||||||
db.data.conversations.findIndex((c) => c.id === id),
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
const deletedMessageIds = db.data.messages
|
|
||||||
.filter((m) => m.conversationId === id)
|
|
||||||
.map((m) => m.id);
|
|
||||||
db.data.messages = db.data.messages.filter(
|
|
||||||
(m) => m.conversationId !== id,
|
|
||||||
);
|
|
||||||
db.data.facts = db.data.facts.filter(
|
|
||||||
(fact) => !deletedMessageIds.includes(fact.sourceMessageId),
|
|
||||||
);
|
|
||||||
db.write();
|
|
||||||
return { ok: true };
|
|
||||||
}),
|
|
||||||
updateConversationTitle: publicProcedure
|
|
||||||
.input(
|
|
||||||
(x) =>
|
|
||||||
x as {
|
|
||||||
id: string;
|
|
||||||
title: string;
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.mutation(async ({ input: { id, title } }) => {
|
|
||||||
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: string })
|
|
||||||
.query(async ({ input: { conversationId } }) => {
|
|
||||||
const rows = await db.data.messages.filter(
|
|
||||||
(m) => m.conversationId === conversationId,
|
|
||||||
);
|
|
||||||
return rows as Array<CommittedMessage>;
|
|
||||||
}),
|
|
||||||
sendMessage: publicProcedure
|
sendMessage: publicProcedure
|
||||||
.input(
|
.input(
|
||||||
(x) =>
|
(x) =>
|
||||||
@@ -395,34 +338,6 @@ export const chat = router({
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
fetchFacts: publicProcedure
|
|
||||||
.input((x) => x as { conversationId: string })
|
|
||||||
.query(async ({ input: { conversationId } }) => {
|
|
||||||
const conversationMessageIds = db.data.messages
|
|
||||||
.filter((m) => m.conversationId === conversationId)
|
|
||||||
.map((m) => m.id);
|
|
||||||
const rows = await db.data.facts.filter((f) =>
|
|
||||||
conversationMessageIds.includes(f.sourceMessageId),
|
|
||||||
);
|
|
||||||
return rows as Array<Fact>;
|
|
||||||
}),
|
|
||||||
deleteFact: publicProcedure
|
|
||||||
.input(
|
|
||||||
(x) =>
|
|
||||||
x as {
|
|
||||||
factId: string;
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.mutation(async ({ input: { factId } }) => {
|
|
||||||
const deletedFact = db.data.facts.find((fact) => fact.id === factId);
|
|
||||||
if (!deletedFact) throw new Error("Fact not found");
|
|
||||||
db.data.facts.splice(
|
|
||||||
db.data.facts.findIndex((fact) => fact.id === factId),
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
db.write();
|
|
||||||
return { ok: true };
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const createCaller = createCallerFactory(chat);
|
export const createCaller = createCallerFactory(chat);
|
||||||
|
|||||||
Reference in New Issue
Block a user