Spaces:
Running
Running
File size: 2,526 Bytes
ff0e173 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 'use client';
import * as React from 'react';
import { ChatMessage } from '@/lib/kb-data';
/**
* Shared chat session logic (messages + RAG request handling).
*
* Extracted so the same conversation engine drives both the dedicated
* `/chat` page and the inline chat on the homepage (`/`).
*/
export function useChatSession() {
const [messages, setMessages] = React.useState<ChatMessage[]>([]);
const [isTyping, setIsTyping] = React.useState(false);
// Monotonic counter guarantees unique keys even within the same millisecond.
const idCounter = React.useRef(0);
const makeId = React.useCallback(
(role: 'user' | 'ai') => `m-${Date.now()}-${idCounter.current++}-${role}`,
[]
);
const sendMessage = React.useCallback(
async (textToSend: string) => {
if (!textToSend.trim()) return;
const userMsg: ChatMessage = {
id: makeId('user'),
sender: 'user',
text: textToSend,
timestamp: new Date().toLocaleTimeString(),
};
setMessages((prev) => [...prev, userMsg]);
setIsTyping(true);
// Query the RAG pipeline: retrieve + rerank + grounded answer with citations.
try {
const res = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query: textToSend }),
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
throw new Error(err.error || `Request failed (${res.status})`);
}
const data: { text: string; sources?: Array<{ name: string; type: string }> } =
await res.json();
const aiMsg: ChatMessage = {
id: makeId('ai'),
sender: 'ai',
text: data.text,
timestamp: new Date().toLocaleTimeString(),
sources: data.sources,
};
setMessages((prev) => [...prev, aiMsg]);
} catch {
const aiMsg: ChatMessage = {
id: makeId('ai'),
sender: 'ai',
text:
"Sorry — I ran into a problem reaching the knowledge base. Please make sure your Cohere API key is configured and try again.",
timestamp: new Date().toLocaleTimeString(),
};
setMessages((prev) => [...prev, aiMsg]);
} finally {
setIsTyping(false);
}
},
[makeId]
);
const reset = React.useCallback(() => {
setMessages([]);
setIsTyping(false);
}, []);
return { messages, isTyping, sendMessage, reset };
}
|