uncloseai.com/uncloseai.js
Russell Ballestrini eee33986cf feat(ui): add comprehensive language localization system
- Add complete UI translations for all 19 supported languages
- Add language preference dropdown in modal settings
- Store language preference in localStorage
- Inject language preference into Hermes system prompts
- Add smart translation dropdown with AI-powered language detection
- Keep both original translation modal and new smart dropdown
- Remove non-functional upload button from modal
- Add biome.json config to ignore third-party CSS files
2025-07-03 11:09:10 -04:00

172 lines
6.4 KiB
JavaScript

/*
* uncloseai.js - Modular AI Integration Library
*
* Main entry point that imports all modules and exports the public API
* This maintains backward compatibility while enabling better code organization
*/
import * as Chat from "./src/chat.js";
// Internal modules
import * as Config from "./src/config.js";
import * as Content from "./src/content.js";
import * as FileUpload from "./src/file-upload.js";
import * as Models from "./src/models.js";
import * as PageReader from "./src/page-reader.js";
import * as Storage from "./src/storage.js";
import * as Translation from "./src/translation.js";
import * as TTS from "./src/tts.js";
import * as UI from "./src/ui.js";
// -------------------------
// Public API - Main Functions
// -------------------------
// Chat functionality
export const sendMessage = Chat.sendMessage;
export const handleUserInput = Chat.handleUserInput;
// TTS functionality
export const speakText = TTS.speakText;
export const processContentWithHermes = TTS.processContentWithHermes;
export const extractSpokenTokens = TTS.extractSpokenTokens;
export const generateTitleForTTS = TTS.generateTitleForTTS;
// File upload
export const uploadFile = FileUpload.uploadFile;
export const integrateMegafarceResponse = FileUpload.integrateMegafarceResponse;
export const showProgressIndicator = FileUpload.showProgressIndicator;
export const hideProgressIndicator = FileUpload.hideProgressIndicator;
// Page reading
export const readPageWithHermes = PageReader.readPageWithHermes;
export const extractWebpageContent = Content.extractWebpageContent;
// Model management
export const getSelectedModel = Models.getSelectedModel;
export const getSelectedModelEndpoint = Models.getSelectedModelEndpoint;
export const fetchModelsFromEndpoints = Models.fetchModelsFromEndpoints;
export const createModelSelectionDropdown = Models.createModelSelectionDropdown;
export const addRefreshModelsButton = Models.addRefreshModelsButton;
// Storage
export const saveConversationHistory = Storage.saveConversationHistory;
export const loadConversationHistory = Storage.loadConversationHistory;
export const clearConversationHistory = Storage.clearConversationHistory;
export const getPageSpecificKey = Storage.getPageSpecificKey;
// UI creation
export const createFloatingAIButton = UI.createFloatingAIButton;
export const initializeUncloseaiElements = UI.initializeUncloseaiElements;
export const createFullInterface = UI.createFullInterface;
export const createCustomInterface = UI.createCustomInterface;
export const toggleUncloseaiEmbeddedModal = UI.toggleUncloseaiEmbeddedModal;
export const openUncloseaiEmbeddedModal = UI.openUncloseaiEmbeddedModal;
export const openTTSModal = UI.openTTSModal;
export const openTranslateModal = UI.openTranslateModal;
// Translation functionality
export const translateText = Translation.translateText;
export const translateCurrentPage = Translation.translateCurrentPage;
// -------------------------
// Configuration and State
// -------------------------
// Export configuration constants
export const TTS_API_URL = Config.TTS_API_URL;
export const MEGAPARCE_API_URL = Config.MEGAPARCE_API_URL;
export const API_KEY = Config.API_KEY;
export const MODEL = Config.MODEL;
export const VLLM_ENDPOINTS = Config.VLLM_ENDPOINTS;
// Export model registry
export const modelRegistry = Models.modelRegistry;
// Export chat history (for external access)
export { chatHistory } from "./src/chat.js";
// -------------------------
// Initialization
// -------------------------
// -------------------------
// Global Scope Exports (for backward compatibility)
// -------------------------
// Export functions to global scope for HTML onclick handlers
window.handleUserInput = Chat.handleUserInput;
window.readPageWithHermes = PageReader.readPageWithHermes;
window.sendMessage = Chat.sendMessage;
window.speakText = TTS.speakText;
window.uploadFile = FileUpload.uploadFile;
window.openTTSModal = UI.openTTSModal;
window.openTranslateModal = UI.openTranslateModal;
window.toggleUncloseaiEmbeddedModal = async () =>
await UI.toggleUncloseaiEmbeddedModal();
window.extractWebpageContent = Content.extractWebpageContent;
window.getSelectedModel = Models.getSelectedModel;
window.getSelectedModelEndpoint = Models.getSelectedModelEndpoint;
window.showProgressIndicator = FileUpload.showProgressIndicator;
window.hideProgressIndicator = FileUpload.hideProgressIndicator;
window.handleTTSFromElement = UI.handleTTSFromElement;
window.handleUploadFromElement = UI.handleUploadFromElement;
window.handleSmartTranslate = UI.handleSmartTranslate;
// Initialize on page load
window.addEventListener("load", () => {
console.log("uncloseai.js: window.onload event fired.");
// Check skip init flag first
if (window.UNCLOSEAI_SKIP_INIT === true) {
console.log(
"uncloseai.js: Skipping full initialization as requested by flag.",
);
console.log(
"uncloseai.js: Creating floating button only for preview windows.",
);
// Still create floating button for preview windows, but skip other initialization
const SHOW_FLOATING_BUTTON = window.UNCLOSEAI_FLOATING_BUTTON !== false;
if (SHOW_FLOATING_BUTTON) {
UI.createFloatingAIButton();
}
return;
}
UI.initializeSystem();
});
// Export helper functions for class-based integrations
window.handleCustomChat = async (button) => {
const container = button.parentElement;
const input = container.querySelector("[data-chat-input]");
const chatBox = container.querySelector("[data-chat-box]");
const message = input.value.trim();
if (!message) return;
// Add user message
chatBox.innerHTML += `<div style="margin: 2px 0; padding: 2px; background: #e3f2fd; border-radius: 2px; font-size: 0.9em;"><strong>You:</strong> ${message}</div>`;
input.value = "";
// Add AI thinking indicator
const thinkingDiv = document.createElement("div");
thinkingDiv.style.cssText =
"margin: 2px 0; padding: 2px; background: #f5f5f5; border-radius: 2px; font-size: 0.9em;";
thinkingDiv.innerHTML = "<strong>AI:</strong> <em>thinking...</em>";
chatBox.appendChild(thinkingDiv);
chatBox.scrollTop = chatBox.scrollHeight;
try {
let response = "";
for await (const chunk of Chat.sendMessage(message)) {
response += chunk;
thinkingDiv.innerHTML = `<strong>AI:</strong> ${response}`;
chatBox.scrollTop = chatBox.scrollHeight;
}
} catch (error) {
thinkingDiv.innerHTML = `<strong>Error:</strong> ${error.message}`;
}
};
console.log("uncloseai.js: Modular version loaded successfully");