diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..7a73a41
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,2 @@
+{
+}
\ No newline at end of file
diff --git a/packages/chat-client/src/App.jsx b/packages/chat-client/src/App.jsx
index 2b11bea..f6fb1d6 100644
--- a/packages/chat-client/src/App.jsx
+++ b/packages/chat-client/src/App.jsx
@@ -1,8 +1,10 @@
-import React, { useState } from 'react';
+import React, { useState, useEffect } from 'react';
import ChatWindow from './components/ChatWindow';
import InfoPanel from './components/InfoPanel';
import Sidebar from './components/Sidebar';
-import {v4 as uuidv4} from 'uuid';
+import HomeView from './components/HomeView';
+import { v4 as uuidv4 } from 'uuid';
+import { getModelProps } from './api/orchestration';
/*** View Panels*** */
import AllChatsView from './components/AllChatsView';
@@ -17,13 +19,30 @@ import { useChat } from './hooks/useChat';
import { useModels } from './hooks/useModels';
import { useProjects } from './hooks/useProjects';
+// Views where back nav makes sense, and where they go back to
+const BACK_MAP = {
+ 'chat': 'home',
+ 'all-chats': 'home',
+ 'all-projects': 'home',
+ 'settings': 'home',
+ 'project': 'all-projects',
+ 'memory': 'settings',
+};
+
export default function App() {
- const [leftOpen, setLeftOpen] = useState(true);
+ const [leftOpen, setLeftOpen] = useState(false); // collapsed on home
const [rightOpen, setRightOpen] = useState(false);
const { models, selectedModel, setSelectedModel } = useModels();
- const [view, setView] = useState('chat')
+ const [view, setView] = useState('home');
+ const [viewHistory, setViewHistory] = useState([]);
const [activeProject, setActiveProject] = useState(null);
- const {projects, refreshProjects} = useProjects();
+ const { projects, refreshProjects } = useProjects();
+
+ // Lifted model props — available to header + SettingsView
+ const [modelProps, setModelProps] = useState(null);
+ useEffect(() => {
+ getModelProps().then(setModelProps).catch(() => {});
+ }, []);
const {
sessions,
@@ -46,17 +65,49 @@ export default function App() {
lastModel,
} = useChat({ activeSession, appendMessage, updateLastMessage, refreshSessions });
+ function navigate(nextView) {
+ setViewHistory(prev => [...prev, view]);
+ setView(nextView);
+ // Expand sidebar when leaving home
+ if (view === 'home') setLeftOpen(true);
+ }
+
+ function goBack() {
+ if (viewHistory.length > 0) {
+ const prev = viewHistory[viewHistory.length - 1];
+ setViewHistory(h => h.slice(0, -1));
+ setView(prev);
+ if (prev === 'home') setLeftOpen(false);
+ } else {
+ // Fallback to BACK_MAP
+ const dest = BACK_MAP[view] ?? 'home';
+ setView(dest);
+ if (dest === 'home') setLeftOpen(false);
+ }
+ }
+
function handleSendMessage(text) {
sendMessage(text, selectedModel, activeSession?.project_id ?? null);
}
- function handleSessionsChange(deletedSession){
- if(deletedSession?.external_id === activeSession?.external_id){
+ function handleSessionsChange(deletedSession) {
+ if (deletedSession?.external_id === activeSession?.external_id) {
selectSession(null);
}
refreshSessions();
}
+ // Home: create session, navigate to chat, then send after a tick
+ function handleHomeSend(text) {
+ createSession();
+ setViewHistory(prev => [...prev, 'home']);
+ setView('chat');
+ setLeftOpen(true);
+ setTimeout(() => {
+ sendMessage(text, selectedModel, null);
+ }, 50);
+ }
+
async function handleNewProjectChat() {
const newSession = {
external_id: uuidv4(),
@@ -64,70 +115,90 @@ export default function App() {
isNew: true,
project_id: activeProject?.id ?? null,
};
- // Optimistically set active session then navigate
setSessions(prev => [newSession, ...prev]);
selectSession(newSession);
- setView('chat');
- // After first message saves, project assignment will be written via updateSession
+ navigate('chat');
}
+ const canGoBack = view !== 'home';
+
return (
-
+
setView('all-projects')}
+ onSelectSession={session => { selectSession(session); navigate('chat'); }}
+ onNewChat={() => { createSession(); navigate('chat'); }}
+ onNewProject={() => navigate('all-projects')}
isOpen={leftOpen}
onToggle={() => setLeftOpen(o => !o)}
onSessionsChange={handleSessionsChange}
- onNavigate={setView}
+ onNavigate={navigate}
projects={projects}
onProjectsChange={refreshProjects}
onSelectProject={setActiveProject}
/>
+ {view === 'home' && (
+
+ )}
{view === 'chat' && (
- setRightOpen(o => !o)}
- />
+ setRightOpen(o => !o)}
+ onBack={goBack}
+ canGoBack={canGoBack}
+ loadedModel={modelProps?.modelAlias ?? null}
+ />
)}
{view === 'all-chats' && (
{selectSession(session); setView('chat');}}
- />
+ onBack={goBack}
+ onSelectSession={session => { selectSession(session); navigate('chat'); }}
+ />
)}
{view === 'all-projects' && (
-
+
)}
- {view === 'settings' && }
+ {view === 'settings' && (
+
+ )}
{view === 'project' && activeProject && (
)}
- {view === 'memory' && }
-
+ {view === 'memory' && (
+
+ )}
);
diff --git a/packages/chat-client/src/components/AllChatsView.jsx b/packages/chat-client/src/components/AllChatsView.jsx
index 845a15e..93f4e8d 100644
--- a/packages/chat-client/src/components/AllChatsView.jsx
+++ b/packages/chat-client/src/components/AllChatsView.jsx
@@ -4,7 +4,7 @@ import { API_DEFAULTS } from '../config/constants';
const PAGE_SIZE = API_DEFAULTS.PAGE_SIZE;
-export default function AllChatsView({ onSelectSession }) {
+export default function AllChatsView({ onSelectSession, onBack }) {
const [sessions, setSessions] = useState([]);
const [loading, setLoading] = useState(true);
const [page, setPage] = useState(0);
@@ -86,10 +86,11 @@ export default function AllChatsView({ onSelectSession }) {
{/* Header */}
-
-
- All Chats
-
+
+
+
+ All Chats
+
{selected.size > 0 && (