// chat.js - Clean AI Chat Interface with Active File + File Context (function () { console.log("[chat] Loading AI Chat interface (clean)…"); // --- Utility Functions --- function escapeHtml(text) { const div = document.createElement("div"); div.textContent = text; return div.innerHTML; } function generateSessionId() { return ( "session_" + Date.now() + "_" + Math.random().toString(36).substr(2, 9) ); } let currentChatMode = localStorage.getItem('chat_currentMode') || 'chat'; function saveChatMode(mode) { currentChatMode = mode; localStorage.setItem('chat_currentMode', mode); console.log('[chat] Mode changed to:', mode); } // --- Get API configuration from Settings module --- function getApiConfig() { if (window.Settings) { const settings = window.Settings.get(); return { endpoint: window.Settings.getApiEndpoint(), defaultModel: settings.defaultModel, maxTokens: settings.maxTokens, temperature: settings.temperature, responseMode: settings.responseMode, }; } // Fallback if Settings not loaded return { endpoint: "api.php", defaultModel: "grok-code-fast-1", maxTokens: 2000, temperature: 0.7, responseMode: "normal", }; } let currentModel = getApiConfig().defaultModel; let sessionId = generateSessionId(); // Listen for settings updates window.addEventListener("settingsUpdated", (e) => { const newSettings = e.detail; currentModel = newSettings.defaultModel; console.log("[chat] Settings updated, new default model:", currentModel); }); // --- API Call Function --- async function callAI(question, systemMessage, conversationHistory) { const config = getApiConfig(); const modelConfig = window.Settings ? window.Settings.getModelConfig(currentModel) : { provider: "unknown", name: currentModel }; try { const response = await fetch(config.endpoint, { method: "POST", headers: { "Content-Type": "application/json", "X-Session-Id": sessionId, "X-Username": "user", // Make dynamic if you add auth }, body: JSON.stringify({ question: question, model: currentModel, system: systemMessage, sessionId: sessionId, maxTokens: config.maxTokens, temperature: config.temperature, }), }); if (!response.ok) { throw new Error("API request failed: " + response.status); } const data = await response.json(); if (data.error) { throw new Error(data.error); } return { answer: data.answer || "(no response)", usage: data.usage, provider: data.provider, model: data.model, }; } catch (error) { console.error("[chat] API Error:", error); throw error; } } // --- File Context Functions --- function getFileContext() { if (!window.FilesManager) { console.warn("[chat] FilesManager not available"); return { active: null, read: [] }; } const files = window.FilesManager.getFiles(); const activeFile = files.find((f) => f.active); const readFiles = files.filter((f) => f.read); return { active: activeFile, read: readFiles, }; } function buildFileContextMessage() { const fileContext = getFileContext(); let contextMessage = ""; if (fileContext.active) { contextMessage += "\n\n## ACTIVE FILE (Primary Context)\n"; contextMessage += "File: " + fileContext.active.name + "\n"; contextMessage += "Path: " + fileContext.active.path + "\n"; contextMessage += "```\n" + fileContext.active.content + "\n```"; } if (fileContext.read.length > 0) { contextMessage += "\n\n## READ FILES (Additional Context)\n"; fileContext.read.forEach(function (file) { contextMessage += "\nFile: " + file.name + "\n"; contextMessage += "Path: " + file.path + "\n"; contextMessage += "```\n" + file.content + "\n```\n"; }); } return contextMessage; } // --- File Context Badge Display --- function renderFileContextBadge() { const fileContext = getFileContext(); if (!fileContext.active && fileContext.read.length === 0) { return `