begin migration to trpc/react-query integration

This commit is contained in:
Avraham Sakal
2025-08-17 19:32:24 -04:00
parent cb749072f2
commit 2d35a4683b
9 changed files with 348 additions and 174 deletions
+41
View File
@@ -0,0 +1,41 @@
import { Card, Textarea } from "@mantine/core";
import { useState } from "react";
import { useTRPC } from "../../trpc/client";
export default function ChatPage() {
const [inputMessage, setInputMessage] = useState("");
const [loading, setLoading] = useState(false);
const [outputMessage, setOutputMessage] = useState("");
const trpc = useTRPC();
async function handleSendMessage() {
setLoading(true);
const response = await trpc.chat.streamMessage.subscribe(
{
message: inputMessage,
},
{}
);
for await (const chunk of response) {
setOutputMessage(chunk);
}
setLoading(false);
}
return (
<div>
<Card>{outputMessage}</Card>
<Textarea
resize="vertical"
placeholder="Type your message here..."
value={inputMessage}
disabled={loading}
onChange={(e) => setInputMessage(e.target.value)}
onKeyDown={async (e) => {
if (e.key === "Enter") {
e.preventDefault();
}
}}
/>
</div>
);
}
+12 -12
View File
@@ -10,7 +10,6 @@ import {
Textarea,
useMantineTheme,
} from "@mantine/core";
import { trpc } from "../../../trpc/client";
import { useEffect, useState } from "react";
import {
defaultParameters,
@@ -23,13 +22,20 @@ import type { Data } from "./+data";
import type { CommittedMessage, DraftMessage } from "../../../types";
import Markdown from "react-markdown";
import { IconTrash, IconEdit, IconCheck, IconX } from "@tabler/icons-react";
import { useTRPCClient } from "../../../trpc/client";
export default function ChatPage() {
const pageContext = usePageContext();
const conversationId = pageContext.routeParams.id;
const conversationTitle = useStore(
(state) => state.conversations.find((c) => c.id === conversationId)?.title
);
const {
conversation,
messages: initialMessages,
facts: initialFacts,
factTriggers: initialFactTriggers,
} = useData<Data>();
const conversationTitle = conversation?.title;
const messages = useStore((state) => state.messages);
const message = useStore((state) => state.message);
const systemPrompt = useStore((state) => state.systemPrompt);
@@ -48,6 +54,7 @@ export default function ChatPage() {
const removeFact = useStore((state) => state.removeFact);
const removeFactTrigger = useStore((state) => state.removeFactTrigger);
const setLoading = useStore((state) => state.setLoading);
const trpc = useTRPCClient();
// State for editing facts
const [editingFactId, setEditingFactId] = useState<string | null>(null);
@@ -84,13 +91,6 @@ export default function ChatPage() {
};
}, [editingFactId, editingFactTriggerId]);
const {
conversation,
messages: initialMessages,
facts: initialFacts,
factTriggers: initialFactTriggers,
} = useData<Data>();
useEffect(() => {
setConversationId(conversationId);
}, [conversationId, setConversationId]);
@@ -162,7 +162,7 @@ export default function ChatPage() {
<span>Conversation #{conversationId} - </span>
<input
type="text"
value={conversationTitle || ""}
defaultValue={conversationTitle || ""}
onChange={(e) => {
setConversationTitle(e.target.value);
}}
+18 -1
View File
@@ -3,7 +3,7 @@ import {
publicProcedure,
createCallerFactory,
} from "../../trpc/server.js";
import { generateObject, generateText, jsonSchema } from "ai";
import { generateObject, generateText, jsonSchema, streamText } from "ai";
import type {
OtherParameters,
CommittedMessage,
@@ -47,6 +47,23 @@ export const chat = router({
messages,
facts,
factTriggers,
streamMessage: publicProcedure
.input(
(x) =>
x as {
message: string;
}
)
.subscription(async function* ({ input, signal }) {
const result = streamText({
model: openrouter(MODEL_NAME),
messages: [{ role: "user" as const, content: input.message }],
abortSignal: signal,
});
for await (const chunk of result.textStream) {
yield chunk;
}
}),
sendMessage: publicProcedure
.input(
(x) =>
+3 -1
View File
@@ -1,5 +1,5 @@
import { trpc } from "../../trpc/client";
import { useState } from "react";
import { useTRPCClient } from "../../trpc/client";
export function TodoList({
initialTodoItems,
@@ -8,6 +8,8 @@ export function TodoList({
}) {
const [todoItems, setTodoItems] = useState(initialTodoItems);
const [newTodo, setNewTodo] = useState("");
const trpc = useTRPCClient();
return (
<>
<ul>