comparison love/epi/src/atoms/chatAtoms.ts @ 38:cf9caa4abc3e

[Love] FE and BE. Can chat and render images. Also created MCP for powerpoint generations.
author MrJuneJune <me@mrjunejune.com>
date Mon, 01 Dec 2025 20:35:56 -0800
parents
children
comparison
equal deleted inserted replaced
37:fb9bcd3145cb 38:cf9caa4abc3e
1 import { atom } from 'jotai';
2 import type { SetStateAction } from 'jotai';
3 import { atomFamily } from 'jotai/utils';
4
5 export type MessageRole = 'user' | 'assistant' | 'system';
6
7 export type Message = {
8 id: string;
9 role: MessageRole;
10 content: string;
11 image_url?: string;
12 type: 'text';
13 };
14
15 export type Chat = {
16 id: string;
17 title: string;
18 messages: Message[];
19 created_at: number;
20 };
21
22 // Global
23 export const chatsAtom = atom<Record<string, Chat>>({});
24 export const currentChatId = atom<string | null>(null);
25
26 export const messagesAtom = atomFamily((chatId: string) =>
27 atom(
28 (get) => get(chatsAtom)[chatId]?.messages ?? [],
29 (get, set, update: SetStateAction<Message[]>) => {
30 const chats = get(chatsAtom);
31 const prevMessages = chats[chatId]?.messages ?? [];
32 const newMessages =
33 typeof update === 'function'
34 ? (update as (prev: Message[]) => Message[])(prevMessages)
35 : update;
36
37 const updatedChat: Chat = {
38 id: chatId,
39 title: chats[chatId]?.title ?? 'New Chat',
40 messages: newMessages,
41 created_at: chats[chatId]?.created_at ?? new Date(),
42 };
43
44 let newChats = { ...chats };
45 if (!chats[chatId]) {
46 newChats = {
47 [chatId]: updatedChat,
48 ...chats,
49 };
50 } else {
51 newChats[chatId] = updatedChat;
52 }
53 set(chatsAtom, newChats);
54 },
55 ),
56 );
57
58 export const addMessageAtom = atom(
59 null,
60 (get, set, { chatId, message }: { chatId: string; message: Omit<Message, 'id' | 'created_at'> | Message }) => {
61 const newMessage: Message = {
62 id: crypto.randomUUID(),
63 ...message,
64 };
65
66 const msgAtom = messagesAtom(chatId);
67 const currentMessages = get(msgAtom);
68 set(msgAtom, [...currentMessages, newMessage]);
69 },
70 );
71
72 export const updateChatTitleAtom = atom(
73 null,
74 (get, set, { chatId, title }: { chatId: string; title: string }) => {
75 const chats = get(chatsAtom);
76 const chat = chats[chatId];
77
78 if (!chat) return;
79
80 set(chatsAtom, {
81 ...chats,
82 [chatId]: {
83 ...chat,
84 title,
85 },
86 });
87 },
88 );