Files
nexusAI/packages/chat-client/src/hooks/useSession.js
2026-04-06 03:25:25 -07:00

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,
};
}