From 75447dc81e83b0dacb15ede3a0ca25ec4e9a8dcc Mon Sep 17 00:00:00 2001 From: MattAgn Date: Sun, 8 Sep 2024 17:36:43 +0200 Subject: [PATCH] feat: include history in bot knowledge --- apps/expo/src/app/chat.tsx | 2 +- .../infra/adaptStreamMessagesToGptMessages.ts | 10 +++++++ packages/api/src/router/chatbot.ts | 28 +++++++++++-------- 3 files changed, 27 insertions(+), 13 deletions(-) create mode 100644 packages/api/src/infra/adaptStreamMessagesToGptMessages.ts diff --git a/apps/expo/src/app/chat.tsx b/apps/expo/src/app/chat.tsx index ef103f0..02a446a 100644 --- a/apps/expo/src/app/chat.tsx +++ b/apps/expo/src/app/chat.tsx @@ -34,7 +34,7 @@ export default function Chat() { return; } - respondToMessage.mutateAsync({ message, channelId }); + respondToMessage.mutateAsync({ channelId }); } catch (error) { console.log(error); } diff --git a/packages/api/src/infra/adaptStreamMessagesToGptMessages.ts b/packages/api/src/infra/adaptStreamMessagesToGptMessages.ts new file mode 100644 index 0000000..7718a80 --- /dev/null +++ b/packages/api/src/infra/adaptStreamMessagesToGptMessages.ts @@ -0,0 +1,10 @@ +import { ChatCompletionMessageParam } from "openai/resources/index.mjs"; +import { DefaultGenerics, Message, MessageResponse } from "stream-chat"; + +export const adaptStreamMessagesToGptMessages = ( + messages: MessageResponse[], +): ChatCompletionMessageParam[] => + messages.map((message) => ({ + role: message?.user?.role === "user" ? "user" : "system", + content: message.text ?? "", + })); diff --git a/packages/api/src/router/chatbot.ts b/packages/api/src/router/chatbot.ts index a579ae9..24b8448 100644 --- a/packages/api/src/router/chatbot.ts +++ b/packages/api/src/router/chatbot.ts @@ -3,6 +3,7 @@ import OpenAI from "openai"; import { StreamChat } from "stream-chat"; import { z } from "zod"; +import { adaptStreamMessagesToGptMessages } from "../infra/adaptStreamMessagesToGptMessages"; import { publicProcedure } from "../trpc"; const client = new OpenAI({ @@ -26,17 +27,28 @@ const coachByChannel: Record = { export const chatbotRouter = { getChatGptResponse: publicProcedure - .input( - z.object({ message: z.string(), channelId: z.nativeEnum(ChannelId) }), - ) + .input(z.object({ channelId: z.nativeEnum(ChannelId) })) .mutation(async ({ input }) => { + if (!STREAM_API_KEY || !STREAM_SECRET) { + throw new Error("STREAM_API_KEY and STREAM_SECRET are required"); + } + + const chatClient = StreamChat.getInstance(STREAM_API_KEY, STREAM_SECRET); + + const channel = chatClient.channel("Chatgpt", input.channelId); + + const { messages: chatHistory } = await channel.query({ + messages: { limit: 30 }, + }); + console.log(chatHistory); + const chatCompletion = await client.chat.completions.create({ messages: [ { role: "system", content: getCoachingPrompt(input.channelId), }, - { role: "user", content: input.message }, + ...adaptStreamMessagesToGptMessages(chatHistory), ], model: "gpt-4o", temperature: 0.2, @@ -46,14 +58,6 @@ export const chatbotRouter = { chatCompletion.choices[0]?.message.content ?? "Sorry i'm asleep right now, come back later"; - if (!STREAM_API_KEY || !STREAM_SECRET) { - throw new Error("STREAM_API_KEY and STREAM_SECRET are required"); - } - - const chatClient = StreamChat.getInstance(STREAM_API_KEY, STREAM_SECRET); - - const channel = chatClient.channel("Chatgpt", input.channelId, {}); - const gptmessage = { text: message, user_id: coachByChannel[input.channelId],