Mercurial
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 ); |