From 9bfe56f7ce6dc412f99a4edef97368b74d78ab57 Mon Sep 17 00:00:00 2001 From: overcuriousity Date: Thu, 18 Jul 2024 21:21:52 +0200 Subject: [PATCH 1/3] fix mobile options --- ui/components/Sidebar.tsx | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/ui/components/Sidebar.tsx b/ui/components/Sidebar.tsx index cc2097d..db6b13e 100644 --- a/ui/components/Sidebar.tsx +++ b/ui/components/Sidebar.tsx @@ -1,5 +1,4 @@ 'use client'; - import { cn } from '@/lib/utils'; import { BookOpenText, Home, Search, SquarePen, Settings } from 'lucide-react'; import Link from 'next/link'; @@ -79,13 +78,13 @@ const Sidebar = ({ children }: { children: React.ReactNode }) => { -
+
{navLinks.map((link, i) => ( {

{link.label}

))} +
{children} From 5b882f4e1372da91ab85549bc2b6d623370a5935 Mon Sep 17 00:00:00 2001 From: overcuriousity Date: Thu, 18 Jul 2024 21:54:02 +0200 Subject: [PATCH 2/3] added persistent storage for the settings --- src/db/schema.ts | 11 +++++++++ src/routes/index.ts | 2 ++ src/routes/settings.ts | 38 ++++++++++++++++++++++++++++++++ ui/components/ChatWindow.tsx | 24 ++++++++++++++++++++ ui/components/SettingsDialog.tsx | 24 +++++++++++--------- 5 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 src/routes/settings.ts diff --git a/src/db/schema.ts b/src/db/schema.ts index 9eefa55..094852d 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -17,3 +17,14 @@ export const chats = sqliteTable('chats', { createdAt: text('createdAt').notNull(), focusMode: text('focusMode').notNull(), }); + +export const settings = sqliteTable('settings', { + id: integer('id').primaryKey(), + chatModelProvider: text('chatModelProvider'), + chatModel: text('chatModel'), + embeddingModelProvider: text('embeddingModelProvider'), + embeddingModel: text('embeddingModel'), + openAIApiKey: text('openAIApiKey'), + openAIBaseURL: text('openAIBaseURL'), + // TODO: add user auth +}); \ No newline at end of file diff --git a/src/routes/index.ts b/src/routes/index.ts index af928ab..a9a0264 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -5,6 +5,7 @@ import configRouter from './config'; import modelsRouter from './models'; import suggestionsRouter from './suggestions'; import chatsRouter from './chats'; +import settingsRouter from './settings'; const router = express.Router(); @@ -14,5 +15,6 @@ router.use('/config', configRouter); router.use('/models', modelsRouter); router.use('/suggestions', suggestionsRouter); router.use('/chats', chatsRouter); +router.use('/settings', settingsRouter); export default router; diff --git a/src/routes/settings.ts b/src/routes/settings.ts new file mode 100644 index 0000000..4fc5967 --- /dev/null +++ b/src/routes/settings.ts @@ -0,0 +1,38 @@ +import express from 'express'; +import db from '../db'; +import { settings } from '../db/schema'; + +const router = express.Router(); + +router.post('/', async (req, res) => { + try { + const { chatModelProvider, chatModel, embeddingModelProvider, embeddingModel, openAIApiKey, openAIBaseURL } = req.body; + + // TODO: Add user authentication + + await db.insert(settings).values({ + chatModelProvider, + chatModel, + embeddingModelProvider, + embeddingModel, + openAIApiKey, + openAIBaseURL, + }).execute(); + + res.status(200).json({ message: 'Settings saved successfully' }); + } catch (err) { + res.status(500).json({ message: 'An error occurred while saving settings' }); + } +}); + +router.get('/', async (req, res) => { + try { + // TODO: Add user authentication + const userSettings = await db.query.settings.findFirst(); + res.status(200).json(userSettings); + } catch (err) { + res.status(500).json({ message: 'An error occurred while fetching settings' }); + } +}); + +export default router; \ No newline at end of file diff --git a/ui/components/ChatWindow.tsx b/ui/components/ChatWindow.tsx index f2c89a3..a0415e0 100644 --- a/ui/components/ChatWindow.tsx +++ b/ui/components/ChatWindow.tsx @@ -21,6 +21,25 @@ export type Message = { sources?: Document[]; }; + +const fetchSettings = async () => { + try { + const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/settings`); + const settings = await res.json(); + + if (settings) { + localStorage.setItem('chatModelProvider', settings.chatModelProvider); + localStorage.setItem('chatModel', settings.chatModel); + localStorage.setItem('embeddingModelProvider', settings.embeddingModelProvider); + localStorage.setItem('embeddingModel', settings.embeddingModel); + localStorage.setItem('openAIApiKey', settings.openAIApiKey); + localStorage.setItem('openAIBaseURL', settings.openAIBaseURL); + } + } catch (err) { + console.error('Failed to fetch settings:', err); + } +}; + const useSocket = ( url: string, setIsWSReady: (ready: boolean) => void, @@ -31,6 +50,8 @@ const useSocket = ( useEffect(() => { if (!ws) { const connectWs = async () => { + await fetchSettings(); + let chatModel = localStorage.getItem('chatModel'); let chatModelProvider = localStorage.getItem('chatModelProvider'); let embeddingModel = localStorage.getItem('embeddingModel'); @@ -306,6 +327,9 @@ const ChatWindow = ({ id }: { id?: string }) => { const messagesRef = useRef([]); + useEffect(() => { + fetchSettings(); + }, []); useEffect(() => { messagesRef.current = messages; }, [messages]); diff --git a/ui/components/SettingsDialog.tsx b/ui/components/SettingsDialog.tsx index 788469b..825553f 100644 --- a/ui/components/SettingsDialog.tsx +++ b/ui/components/SettingsDialog.tsx @@ -146,31 +146,35 @@ const SettingsDialog = ({ const handleSubmit = async () => { setIsUpdating(true); - + try { - await fetch(`${process.env.NEXT_PUBLIC_API_URL}/config`, { + await fetch(`${process.env.NEXT_PUBLIC_API_URL}/settings`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify(config), + body: JSON.stringify({ + chatModelProvider: selectedChatModelProvider, + chatModel: selectedChatModel, + embeddingModelProvider: selectedEmbeddingModelProvider, + embeddingModel: selectedEmbeddingModel, + openAIApiKey: customOpenAIApiKey, + openAIBaseURL: customOpenAIBaseURL, + }), }); - + + // Still keep localStorage for quick access on the client-side localStorage.setItem('chatModelProvider', selectedChatModelProvider!); localStorage.setItem('chatModel', selectedChatModel!); - localStorage.setItem( - 'embeddingModelProvider', - selectedEmbeddingModelProvider!, - ); + localStorage.setItem('embeddingModelProvider', selectedEmbeddingModelProvider!); localStorage.setItem('embeddingModel', selectedEmbeddingModel!); localStorage.setItem('openAIApiKey', customOpenAIApiKey!); localStorage.setItem('openAIBaseURL', customOpenAIBaseURL!); } catch (err) { - console.log(err); + console.error(err); } finally { setIsUpdating(false); setIsOpen(false); - window.location.reload(); } }; From f321bfe41e17173c5eae12ff7cc3adc24f09cfe2 Mon Sep 17 00:00:00 2001 From: overcuriousity Date: Thu, 18 Jul 2024 22:42:55 +0200 Subject: [PATCH 3/3] fix for persistant settings management --- src/routes/settings.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/routes/settings.ts b/src/routes/settings.ts index 4fc5967..6400286 100644 --- a/src/routes/settings.ts +++ b/src/routes/settings.ts @@ -1,15 +1,15 @@ import express from 'express'; import db from '../db'; -import { settings } from '../db/schema'; - +import { settings, eq } from '../db/schema'; const router = express.Router(); router.post('/', async (req, res) => { try { const { chatModelProvider, chatModel, embeddingModelProvider, embeddingModel, openAIApiKey, openAIBaseURL } = req.body; - // TODO: Add user authentication - + + await db.delete(settings).execute(); + await db.insert(settings).values({ chatModelProvider, chatModel, @@ -21,6 +21,7 @@ router.post('/', async (req, res) => { res.status(200).json({ message: 'Settings saved successfully' }); } catch (err) { + console.error('Error saving settings:', err); res.status(500).json({ message: 'An error occurred while saving settings' }); } }); @@ -29,8 +30,12 @@ router.get('/', async (req, res) => { try { // TODO: Add user authentication const userSettings = await db.query.settings.findFirst(); + if (!userSettings) { + return res.status(404).json({ message: 'No settings found' }); + } res.status(200).json(userSettings); } catch (err) { + console.error('Error fetching settings:', err); res.status(500).json({ message: 'An error occurred while fetching settings' }); } });