Fix: Detección de Contexto Según Tema

This commit is contained in:
2025-11-20 10:52:46 -03:00
parent 83a48e16da
commit c94936d56e
4 changed files with 246 additions and 213 deletions

View File

@@ -137,4 +137,17 @@ opacity: 0.8;
text-align: right;
margin-top: 4px;
margin-right: 15px;
}
.context-indicator {
padding: 5px 15px;
background-color: #e9e9eb;
font-size: 0.8rem;
color: #555;
text-align: center;
border-top: 1px solid #ccc;
}
.context-indicator span {
font-weight: bold;
}

View File

@@ -34,6 +34,7 @@ const Chatbot: React.FC = () => {
const [inputValue, setInputValue] = useState('');
const [isLoading, setIsLoading] = useState(false);
const messagesEndRef = useRef<null | HTMLDivElement>(null);
const [activeArticleUrl, setActiveArticleUrl] = useState<string | null>(null);
// Añadimos un useEffect para guardar los mensajes.
useEffect(() => {
@@ -78,10 +79,15 @@ const Chatbot: React.FC = () => {
setMessages(prev => [...prev, botMessagePlaceholder]);
try {
const requestBody = {
message: messageToSend,
contextUrl: activeArticleUrl
};
const response = await fetch(`${import.meta.env.VITE_API_BASE_URL}/api/chat/stream-message`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: messageToSend }),
body: JSON.stringify(requestBody),
});
if (!response.ok || !response.body) {
@@ -90,50 +96,54 @@ const Chatbot: React.FC = () => {
const reader = response.body.getReader();
const decoder = new TextDecoder();
let accumulatedResponse = ''; // Variable para acumular el texto crudo
const readStream = async () => {
let fullReply = '';
while (true) {
const { done, value } = await reader.read();
if (done) {
// El stream ha terminado, no hacemos nada más aquí.
let finalCleanText = '';
try {
const parsedArray = JSON.parse(fullReply.replace(/,$/, '') + ']');
finalCleanText = Array.isArray(parsedArray) ? parsedArray.join('') : fullReply;
} catch (e) {
finalCleanText = fullReply.replace(/^\["|"]$|","/g, '');
}
const linkRegex = /\[.*?\]\((https?:\/\/[^\s]+)\)/;
const match = finalCleanText.match(linkRegex);
// --- INICIO DE LA CORRECCIÓN ---
// Si encontramos un nuevo enlace, actualizamos el contexto.
// Si NO encontramos un enlace, ya no hacemos nada, permitiendo que el contexto anterior persista.
if (match && match[1]) {
console.log("Noticia activa establecida:", match[1]);
setActiveArticleUrl(match[1]);
}
// HEMOS ELIMINADO EL BLOQUE "ELSE" QUE RESETEABA EL CONTEXTO.
// --- FIN DE LA CORRECCIÓN ---
break;
}
// Acumulamos la respuesta cruda que viene del backend
accumulatedResponse += decoder.decode(value);
// ... (el resto del bucle while sigue exactamente igual)
const chunk = decoder.decode(value);
fullReply += chunk;
let cleanText = '';
try {
// Intentamos limpiar la respuesta acumulada
// 1. Parseamos como si fuera un array JSON
const parsedArray = JSON.parse(accumulatedResponse
// Añadimos un corchete de cierre por si el stream se corta a la mitad
.replace(/,$/, '') + ']');
// 2. Unimos los fragmentos del array en un solo texto
const cleanText = Array.isArray(parsedArray) ? parsedArray.join('') : accumulatedResponse;
// 3. Actualizamos el estado con el texto limpio
setMessages(prev => {
const lastMessage = prev[prev.length - 1];
const updatedLastMessage = { ...lastMessage, text: cleanText };
return [...prev.slice(0, -1), updatedLastMessage];
});
const parsedArray = JSON.parse(fullReply.replace(/,$/, '') + ']');
cleanText = Array.isArray(parsedArray) ? parsedArray.join('') : fullReply;
} catch (e) {
// Si hay un error de parseo (porque el JSON aún no está completo),
// mostramos el texto sin los caracteres iniciales/finales.
const partiallyCleanedText = accumulatedResponse
.replace(/^\[?"|"?,"?|"?\]$/g, '')
.replace(/","/g, '');
setMessages(prev => {
const lastMessage = prev[prev.length - 1];
const updatedLastMessage = { ...lastMessage, text: partiallyCleanedText };
return [...prev.slice(0, -1), updatedLastMessage];
});
cleanText = fullReply.replace(/^\["|"]$|","/g, '');
}
setMessages(prev => {
const lastMessage = prev[prev.length - 1];
const updatedLastMessage = { ...lastMessage, text: cleanText };
return [...prev.slice(0, -1), updatedLastMessage];
});
}
};
@@ -176,6 +186,11 @@ const Chatbot: React.FC = () => {
))}
<div ref={messagesEndRef} />
</div>
{activeArticleUrl && (
<div className="context-indicator">
Hablando sobre: <span>Noticia actual</span>
</div>
)}
<form className="input-form" onSubmit={handleSendMessage}>
<div className="input-container">
<input