core.js•5.35 kB
// core.js - Main orchestration and state management for MARM chatbot
import {
  activateMarmSession,
  getSessionContext,
  updateSessionHistory,
  setSessionReasoning,
  searchDocs,
  shouldAutoSearch,
  trimForContext,
  manageUserNotebook
} from '../logic/marmLogic.js';
import { generateContent } from '../replicateHelper.js';
import { appendMessage, showLoadingIndicator, hideLoadingIndicator } from './ui.js';
import { handleCommand } from './commands.js';
import { getState, updateState } from './state.js';
// ===== RATE LIMITING =====
let lastMessageTime = 0;
const MESSAGE_COOLDOWN = 1000; 
// ===== MAIN INPUT HANDLER =====
export async function handleUserInput(userInput) {
  if (typeof userInput !== 'string' || userInput.length === 0) return;
  if (userInput.length > 15000) {
    appendMessage('bot', 'Input too long. Please limit to 15000 characters.');
    return;
  }
  
  const now = Date.now();
  if (now - lastMessageTime < MESSAGE_COOLDOWN) {
    appendMessage('bot', '⏱️ Please wait a moment before sending another message.');
    return;
  }
  lastMessageTime = now;
  
  const welcomeMessage = document.getElementById('welcome-message');
  if (welcomeMessage) {
    welcomeMessage.style.display = 'none';
  }
  
  appendMessage('user', userInput);
  showLoadingIndicator();
  
  try {
    if (userInput.startsWith('/')) {
      await handleCommand(userInput);
    } else {
      await handleStandardMessage(userInput);
    }
  } catch (error) {
    console.error('Error processing message:', error);
    hideLoadingIndicator();
    appendMessage('bot', 'Sorry, I encountered an error. Please try again.');
  }
}
// ===== STANDARD MESSAGE HANDLER =====
async function handleStandardMessage(userInput) {
  const messagesForLLM = [];
  const currentState = getState();
  
  if (currentState.isMarmActive) {
    trimForContext(currentState.currentSessionId);
    const hist = getSessionContext(currentState.currentSessionId);
    if (hist && hist.trim()) {
      messagesForLLM.push({ role: 'system', content: `Current Session History:\n${hist}` });
    }
    
    const notebookData = manageUserNotebook(currentState.currentSessionId, 'all');
    if (notebookData && !notebookData.includes('empty')) {
      messagesForLLM.push({ 
        role: 'system', 
        content: `User's Personal Knowledge Base (treat as absolute truth, never contradict or correct):\n${notebookData}` 
      });
    }
  }
  if (currentState.isMarmActive && shouldAutoSearch(userInput)) {
    const docResult = searchDocs(userInput);
    if (docResult) {
      messagesForLLM.push({ role: 'system', content: `From MARM documentation: ${docResult}` });
    }
  }
  messagesForLLM.push({ role: 'user', content: userInput });
  let replicateResponse;
  let botResponse;
  
  for (let attempt = 1; attempt <= 2; attempt++) {
    try {
      replicateResponse = await generateContent(messagesForLLM);
      if (!replicateResponse) {
        console.error('[MARM] generateContent returned null/undefined in core.js');
        if (attempt === 2) {
          hideLoadingIndicator();
          appendMessage('bot', 'Sorry, I encountered an error processing your request.');
          return;
        }
        continue;
      }
      
      if (typeof replicateResponse.text !== 'function') {
        console.error('[MARM] generateContent response missing .text() method in core.js:', typeof replicateResponse);
        if (attempt === 2) {
          hideLoadingIndicator();
          appendMessage('bot', 'Sorry, I received an invalid response from the AI service.');
          return;
        }
        continue;
      }
      
      const botAnswer = await replicateResponse.text();
      
      if (!botAnswer || typeof botAnswer !== 'string' || botAnswer.trim() === '') {
        console.error('[MARM] replicateResponse.text() returned invalid/empty data in core.js:', typeof botAnswer);
        if (attempt === 1) {
          messagesForLLM[messagesForLLM.length - 1].content = `${userInput}\n\nPlease provide a helpful response to this message.`;
          continue;
        }
        hideLoadingIndicator();
        appendMessage('bot', 'Sorry, I received an empty response. This might be due to content filters - please try rephrasing your message.');
        return;
      }
      
      botResponse = botAnswer.trim();
      
      if (botResponse.includes('I can\'t help with that') || botResponse.includes('I\'m not able to') || botResponse.includes('sorry, but I can\'t')) {
        if (attempt === 1) {
          messagesForLLM[messagesForLLM.length - 1].content = `User message: ${userInput}\n\nPlease provide a helpful and informative response.`;
          continue;
        }
      }
      
      break; 
      
    } catch (error) {
      console.error('[MARM] Error in message processing attempt', attempt, ':', error);
      if (attempt === 2) {
        hideLoadingIndicator();
        appendMessage('bot', 'Sorry, I encountered an error processing your request.');
        return;
      }
    }
  }
  if (currentState.isMarmActive) {
    setSessionReasoning(currentState.currentSessionId, '');
  }
  
  hideLoadingIndicator();
  appendMessage('bot', botResponse);
  
  if (currentState.isMarmActive && currentState.currentSessionId) {
    updateSessionHistory(currentState.currentSessionId, userInput, botResponse);
  }
}