refactoring and clean up of chat cliet
This commit is contained in:
@@ -5,7 +5,7 @@ import InfoPanel from './components/InfoPanel';
|
|||||||
import { useSession } from './hooks/useSession';
|
import { useSession } from './hooks/useSession';
|
||||||
import { useChat } from './hooks/useChat';
|
import { useChat } from './hooks/useChat';
|
||||||
|
|
||||||
const DEFAULT_MODEL = 'companion:latest';
|
import { DEFAULT_MODEL } from './config/constants';
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const [leftOpen, setLeftOpen] = useState(true);
|
const [leftOpen, setLeftOpen] = useState(true);
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
|
import { API_DEFAULTS } from "../config/constants";
|
||||||
|
|
||||||
const BASE_URL = import.meta.env.VITE_ORCHESTRATION_URL ?? '';
|
const BASE_URL = import.meta.env.VITE_ORCHESTRATION_URL ?? '';
|
||||||
|
|
||||||
// ── Sessions ────────────────────────────────────────────────
|
// ── Sessions ────────────────────────────────────────────────
|
||||||
|
|
||||||
export async function fetchSessions(limit = 20, offset = 0) {
|
export async function fetchSessions(limit = API_DEFAULTS.SESSIONS_LIMIT, offset = API_DEFAULTS.OFFSET) {
|
||||||
const res = await fetch(`${BASE_URL}/sessions?limit=${limit}&offset=${offset}`);
|
const res = await fetch(`${BASE_URL}/sessions?limit=${limit}&offset=${offset}`);
|
||||||
if (!res.ok) throw new Error(`Failed to fetch sessions: ${res.status}`);
|
if (!res.ok) throw new Error(`Failed to fetch sessions: ${res.status}`);
|
||||||
return res.json();
|
return res.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchSessionHistory(sessionId, limit = 50, offset = 0) {
|
export async function fetchSessionHistory(sessionId, limit = API_DEFAULTS.HISTORY_LIMIT, offset = API_DEFAULTS.OFFSET) {
|
||||||
const res = await fetch(`${BASE_URL}/sessions/${sessionId}/history?limit=${limit}&offset=${offset}`);
|
const res = await fetch(`${BASE_URL}/sessions/${sessionId}/history?limit=${limit}&offset=${offset}`);
|
||||||
if (!res.ok) throw new Error(`Failed to fetch history: ${res.status}`);
|
if (!res.ok) throw new Error(`Failed to fetch history: ${res.status}`);
|
||||||
return res.json();
|
return res.json();
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { MODELS } from '../config/constants';
|
||||||
const MODELS = [
|
|
||||||
{ value: 'companion:latest', label: 'Companion' },
|
|
||||||
{ value: 'mistral-nemo:latest', label: 'Mistral Nemo' },
|
|
||||||
{ value: 'coder:latest', label: 'Coder' },
|
|
||||||
{ value: 'qwen2.5-coder:14b', label: 'Qwen 2.5 Coder 14B' },
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function InfoPanel({ isOpen, onToggle, activeSession, lastModel, lastTokenCount, selectedModel, onModelChange }) {
|
export default function InfoPanel({ isOpen, onToggle, activeSession, lastModel, lastTokenCount, selectedModel, onModelChange }) {
|
||||||
|
|
||||||
|
|||||||
14
packages/chat-client/src/config/constants.js
Normal file
14
packages/chat-client/src/config/constants.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export const MODELS = [
|
||||||
|
{ value: 'companion:latest', label: 'Companion' },
|
||||||
|
{ value: 'mistral-nemo:latest', label: 'Mistral Nemo' },
|
||||||
|
{ value: 'coder:latest', label: 'Coder' },
|
||||||
|
{ value: 'qwen2.5-coder:14b', label: 'Qwen 2.5 Coder 14B' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const DEFAULT_MODEL = MODELS[0].value;
|
||||||
|
|
||||||
|
export const API_DEFAULTS = {
|
||||||
|
SESSIONS_LIMIT: 20,
|
||||||
|
HISTORY_LIMIT: 50,
|
||||||
|
OFFSET: 0,
|
||||||
|
}
|
||||||
@@ -9,18 +9,27 @@ export function useSession() {
|
|||||||
const [loadingHistory, setLoadingHistory] = useState(false);
|
const [loadingHistory, setLoadingHistory] = useState(false);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
|
|
||||||
// Load session list on mount
|
|
||||||
useEffect(() => {
|
|
||||||
loadSessions();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
async function loadSessions() {
|
// Called by useChat after a message completes — keeps session list fresh
|
||||||
|
const refreshSessions = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
const data = await fetchSessions();
|
const data = await fetchSessions();
|
||||||
setSessions(data);
|
setSessions(data);
|
||||||
} catch (err) {
|
} catch {
|
||||||
setError(err.message);
|
// non-critical — sidebar just won't update
|
||||||
}
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Load session list on mount
|
||||||
|
useEffect(() => {
|
||||||
|
refreshSessions();
|
||||||
|
}, [refreshSessions]);
|
||||||
|
|
||||||
|
function episodesToMessages(episodes) {
|
||||||
|
return [...episodes].reverse().flatMap(ep => [
|
||||||
|
{ id: `${ep.id}-user`, role: 'user', text: ep.user_message },
|
||||||
|
{ id: `${ep.id}-ai`, role: 'assistant', text: ep.ai_response },
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch to an existing session and load its history
|
// Switch to an existing session and load its history
|
||||||
@@ -32,10 +41,7 @@ export function useSession() {
|
|||||||
try {
|
try {
|
||||||
const data = await fetchSessionHistory(session.external_id);
|
const data = await fetchSessionHistory(session.external_id);
|
||||||
// History comes back newest-first — reverse for display
|
// History comes back newest-first — reverse for display
|
||||||
const history = data.episodes.reverse().map(ep => ([
|
const history = episodesToMessages(data.episodes);
|
||||||
{ id: `${ep.id}-user`, role: 'user', text: ep.user_message },
|
|
||||||
{ id: `${ep.id}-ai`, role: 'assistant', text: ep.ai_response },
|
|
||||||
])).flat();
|
|
||||||
|
|
||||||
setMessages(history);
|
setMessages(history);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -58,15 +64,7 @@ export function useSession() {
|
|||||||
setMessages([]);
|
setMessages([]);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Called by useChat after a message completes — keeps session list fresh
|
|
||||||
const refreshSessions = useCallback(async () => {
|
|
||||||
try {
|
|
||||||
const data = await fetchSessions();
|
|
||||||
setSessions(data);
|
|
||||||
} catch {
|
|
||||||
// non-critical — sidebar just won't update
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Append a message to the current thread (used by useChat)
|
// Append a message to the current thread (used by useChat)
|
||||||
const appendMessage = useCallback((message) => {
|
const appendMessage = useCallback((message) => {
|
||||||
|
|||||||
@@ -23,4 +23,9 @@ html, body, #root {
|
|||||||
background: var(--bg-base);
|
background: var(--bg-base);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
0%, 100% { opacity: 1; }
|
||||||
|
50% { opacity: 0; }
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user