97 lines
2.8 KiB
JavaScript
97 lines
2.8 KiB
JavaScript
import { useState, useEffect, useCallback } from 'react';
|
|
import { fetchSessions, fetchSessionHistory } from '../api/orchestration';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
export function useSession() {
|
|
const [sessions, setSessions] = useState([]);
|
|
const [activeSession, setActiveSession] = useState(null);
|
|
const [messages, setMessages] = useState([]);
|
|
const [loadingHistory, setLoadingHistory] = useState(false);
|
|
const [error, setError] = useState(null);
|
|
|
|
// Load session list on mount
|
|
useEffect(() => {
|
|
loadSessions();
|
|
}, []);
|
|
|
|
async function loadSessions() {
|
|
try {
|
|
const data = await fetchSessions();
|
|
setSessions(data);
|
|
} catch (err) {
|
|
setError(err.message);
|
|
}
|
|
}
|
|
|
|
// Switch to an existing session and load its history
|
|
const selectSession = useCallback(async (session) => {
|
|
setActiveSession(session);
|
|
setMessages([]);
|
|
setLoadingHistory(true);
|
|
|
|
try {
|
|
const data = await fetchSessionHistory(session.external_id);
|
|
// History comes back newest-first — reverse for display
|
|
const history = data.episodes.reverse().map(ep => ([
|
|
{ id: `${ep.id}-user`, role: 'user', text: ep.user_message },
|
|
{ id: `${ep.id}-ai`, role: 'assistant', text: ep.ai_response },
|
|
])).flat();
|
|
|
|
setMessages(history);
|
|
} catch (err) {
|
|
setError(err.message);
|
|
} finally {
|
|
setLoadingHistory(false);
|
|
}
|
|
}, []);
|
|
|
|
// Create a new session with a generated UUID — no backend call needed yet,
|
|
// orchestration auto-creates the session on the first message
|
|
const createSession = useCallback(() => {
|
|
const newSession = {
|
|
external_id: uuidv4(),
|
|
metadata: null,
|
|
isNew: true, // flag so SessionList can style it differently
|
|
};
|
|
setSessions(prev => [newSession, ...prev]);
|
|
setActiveSession(newSession);
|
|
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)
|
|
const appendMessage = useCallback((message) => {
|
|
setMessages(prev => [...prev, message]);
|
|
}, []);
|
|
|
|
// Update the last message in the thread (used by useChat during streaming)
|
|
const updateLastMessage = useCallback((updater) => {
|
|
setMessages(prev => {
|
|
const updated = [...prev];
|
|
updated[updated.length - 1] = updater(updated[updated.length - 1]);
|
|
return updated;
|
|
});
|
|
}, []);
|
|
|
|
return {
|
|
sessions,
|
|
activeSession,
|
|
messages,
|
|
loadingHistory,
|
|
error,
|
|
selectSession,
|
|
createSession,
|
|
refreshSessions,
|
|
appendMessage,
|
|
updateLastMessage,
|
|
};
|
|
} |