🤖 LLM Hub

AI Tools Suite

Inspirado en LLM Hub + Playground + g4f — 100% offline, procesamiento local con WASM

Chat
Conversaciones multi-turno con memoria RAG
Vibe Coder
Genera apps web en tiempo real
AI Agent
Genera comandos terminal autónomos
Translator
Traduce texto entre idiomas offline
Writing Aid
Resume, expande, reescribe texto
Scam Detector
Analiza mensajes de phishing
creAItor
Diseña personalidades IA
Transcriber
Voz a texto en el dispositivo
VibeVoice
Chat de voz manos libres
Image Upscale
Superresolución 2x/4x
Modelos GGUF
Carga modelos .gguf del cliente
Personas
Crea y gestiona personalidades IA
Roleplay
Chatea con personajes en rol
Coding Assistant
Asistente de codigo con editor
Characters
Biblioteca de personajes para roleplay
Providers
Configura multiples proveedores AI
App Store
Mini-apps y herramientas

Chat

Conversación local. Grok Build usa el ejecutable local con herramientas de solo lectura.

Configurar Grok Build

💻 Vibe Coder

Describe tu app y mírala construirse en tiempo real


      
    

🤖 AI Agent Terminal

Genera comandos shell autónomos — puedes editar antes de ejecutar

cyrah@agent:~$ Ready. Describe una tarea para generar un comando.

🌍 Translator

✍️ Writing Aid

🛡️ Scam Detector

🎭 creAItor — Diseñador de Personalidades IA

🎙️ Transcriber — Voz a Texto

Procesamiento 100% en el dispositivo via Web Speech API

🗣️ VibeVoice — Chat de Voz

Manos libres: habla y escucha la respuesta

🔍 Image Upscale

Superresolución 2x/4x con canvas

Original
Upscaled

📦 Modelos GGUF — Carga del Cliente

📁 Arrastra un archivo .gguf aquí o haz click para seleccionar

Personas — Gestiona Personalidades IA

Roleplay — Chatea con Personajes

Coding Assistant

Describe lo que necesitas y genera codigo


      
    

Characters — Biblioteca de Personajes

Providers — Configura Proveedores AI

Selecciona el proveedor activo. WASM local siempre disponible.

App Store — Mini-Apps y Herramientas

`; }); // ── AI Agent ── document.getElementById('agentGen').addEventListener('click', async () => { const intent = document.getElementById('agentInput').value.trim(); if(!intent) return; const term = document.getElementById('agentTerminal'); term.innerHTML += `
cyrah@agent:~$ ${intent}`; const result = await LLMHub.agentCommand(intent); if (result.error) { term.innerHTML += `
${result.error}`; return; } term.innerHTML += `
→ CMD: ${result.command}`; term.innerHTML += `
[Editable — puedes modificar antes de ejecutar]`; term.scrollTop = term.scrollHeight; }); // ── Translator ── document.getElementById('trBtn').addEventListener('click', () => { const text = document.getElementById('trInput').value; const from = document.getElementById('trFrom').value; const to = document.getElementById('trTo').value; document.getElementById('trOutput').value = LLMHub.translate(text, from, to); }); // ── Writing Aid ── document.getElementById('waBtn').addEventListener('click', async () => { const text = document.getElementById('waInput').value; const mode = document.getElementById('waMode').value; document.getElementById('waOutput').value = await LLMHub.writingAid(text, mode); }); // ── Scam Detector ── document.getElementById('scamBtn').addEventListener('click', () => { const msg = document.getElementById('scamInput').value; const result = LLMHub.scamDetect(msg); document.getElementById('scamResult').style.display = 'block'; const levelEl = document.getElementById('scamLevel'); levelEl.textContent = result.level === 'Bajo' ? '✅ Bajo' : result.level === 'Medio' ? '⚠️ Medio' : '🔴 Alto'; levelEl.style.color = result.level === 'Bajo' ? '#22c55e' : result.level === 'Medio' ? '#facc15' : '#ef4444'; document.getElementById('scamRisk').textContent = `Riesgo: ${result.risk}%`; const bar = document.getElementById('scamBar'); bar.style.width = result.risk + '%'; bar.style.background = result.level === 'Bajo' ? '#22c55e' : result.level === 'Medio' ? '#facc15' : '#ef4444'; document.getElementById('scamReasons').innerHTML = result.reasons.map(r => `
• ${r}
`).join(''); }); // ── creAItor ── let personas = []; document.getElementById('pCreate').addEventListener('click', () => { const name = document.getElementById('pName').value.trim(); const traits = document.getElementById('pTraits').value.split(',').map(t=>t.trim()).filter(Boolean); const prompt = document.getElementById('pPrompt').value.trim(); if(!name) { toast('Escribe un nombre','error'); return; } const persona = LLMHub.createPersona(name, traits, prompt); personas.push(persona); renderPersonas(); toast('Persona creada','success'); document.getElementById('pName').value = ''; document.getElementById('pTraits').value = ''; document.getElementById('pPrompt').value = ''; }); function renderPersonas() { document.getElementById('personaList').innerHTML = personas.map(p => `
${p.name}
Rasgos: ${p.traits.join(', ')||'N/A'}
Prompt: ${p.systemPrompt.substring(0, 100)}...
` ).join(''); } // ── Transcriber ── let trInstance = null; document.getElementById('trStart').addEventListener('click', () => { trInstance = LLMHub.transcribe( text => { document.getElementById('trResult').value = text; }, () => { toast('Transcripción finalizada','success'); } ); if(trInstance.error) toast(trInstance.error,'error'); else toast('Escuchando...','success'); }); document.getElementById('trStop').addEventListener('click', () => { if(trInstance && trInstance.stop) trInstance.stop(); }); // ── VibeVoice ── let vvInstance = LLMHub.vibeVoice(); let vvListening = false; document.getElementById('vvListen').addEventListener('click', () => { if(vvListening) return; vvListening = true; const rec = LLMHub.transcribe(async text => { const box = document.getElementById('voiceChatBox'); const u = document.createElement('div'); u.className='chat-msg user'; u.textContent=text; box.appendChild(u); const a = document.createElement('div'); a.className='chat-msg assistant'; a.textContent='...'; box.appendChild(a); const reply = await LLMHub.chat(text); a.textContent = reply; vvInstance.speak(reply); box.scrollTop = box.scrollHeight; }); if(rec.error) toast(rec.error,'error'); vvListening = rec.recognition ? true : false; }); document.getElementById('vvSpeak').addEventListener('click', () => { const last = document.querySelectorAll('#voiceChatBox .chat-msg.assistant'); if(last.length) vvInstance.speak(last[last.length-1].textContent); }); document.getElementById('vvStop').addEventListener('click', () => { vvInstance.stop(); }); // ── Image Upscale ── let upsImage = null; document.getElementById('upsFile').addEventListener('change', e => { const file = e.target.files[0]; if(!file) return; const reader = new FileReader(); reader.onload = ev => { const img = new Image(); img.onload = () => { upsImage = img; const c = document.getElementById('upsOriginal'); c.width=img.width; c.height=img.height; c.getContext('2d').drawImage(img,0,0); }; img.src = ev.target.result; }; reader.readAsDataURL(file); }); document.getElementById('upsBtn').addEventListener('click', () => { if(!upsImage) { toast('Selecciona una imagen','error'); return; } const scale = parseInt(document.getElementById('upsScale').value); const c1 = document.getElementById('upsOriginal'); const imageData = c1.getContext('2d').getImageData(0,0,c1.width,c1.height); const upscaled = LLMHub.upscaleImage(imageData, scale); const c2 = document.getElementById('upsResult'); c2.width = upscaled.width; c2.height = upscaled.height; c2.getContext('2d').putImageData(upscaled, 0, 0); toast(`Upscaled ${scale}x → ${c2.width}×${c2.height}`,'success'); }); // ── GGUF Model Loader ── const drop = document.getElementById('ggufDrop'); const fileInput = document.getElementById('ggufFile'); drop.addEventListener('click', () => fileInput.click()); drop.addEventListener('dragover', e => { e.preventDefault(); drop.classList.add('dragover'); }); drop.addEventListener('dragleave', () => drop.classList.remove('dragover')); drop.addEventListener('drop', e => { e.preventDefault(); drop.classList.remove('dragover'); if(e.dataTransfer.files[0]) loadGguf(e.dataTransfer.files[0]); }); fileInput.addEventListener('change', e => { if(e.target.files[0]) loadGguf(e.target.files[0]); }); async function loadGguf(file) { toast('Cargando ' + file.name + '...','success'); const result = await LLMHub.loadModel(file); if(result.success) { toast('Modelo cargado: ' + result.model.architecture, 'success'); renderModels(); } else toast(result.error, 'error'); } function renderModels() { const models = LLMHub.getModels(); document.getElementById('modelList').innerHTML = models.length ? models.map(m => `
${m.name}
${m.size} • ${m.architecture} • ${m.quantization} • ctx: ${m.contextLength}
` ).join('') : '
No hay modelos cargados
'; } document.addEventListener('models-updated', renderModels); // ── Personas ── function renderPersonasList() { const list = LLMHub.getPersonas(); document.getElementById('personasList').innerHTML = list.length ? list.map(p => `
${p.name}
Tags: ${(p.tags||[]).join(', ')||'N/A'}
Prompt: ${(p.systemPrompt||'').substring(0,100)}...
` ).join('') : '
No hay personas creadas
'; } document.getElementById('psSave').addEventListener('click', () => { const name = document.getElementById('psName').value.trim(); const tags = document.getElementById('psTags').value.split(',').map(t=>t.trim()).filter(Boolean); const prompt = document.getElementById('psPrompt').value.trim(); if(!name) { toast('Escribe un nombre','error'); return; } LLMHub.savePersona({ name, tags, systemPrompt: prompt || 'Eres ' + name + ', un asistente IA.' }); document.getElementById('psName').value=''; document.getElementById('psTags').value=''; document.getElementById('psPrompt').value=''; renderPersonasList(); updateRoleplaySelect(); toast('Persona guardada','success'); }); renderPersonasList(); // ── Roleplay ── function updateRoleplaySelect() { const personas = LLMHub.getPersonas(); document.getElementById('rpPersona').innerHTML = personas.length ? personas.map(p => ``).join('') : ''; } updateRoleplaySelect(); document.getElementById('rpSend').addEventListener('click', async () => { const pid = document.getElementById('rpPersona').value; const msg = document.getElementById('rpInput').value.trim(); if(!msg || !pid) return; const box = document.getElementById('rpChatBox'); const u = document.createElement('div'); u.className='chat-msg user'; u.textContent=msg; box.appendChild(u); const a = document.createElement('div'); a.className='chat-msg assistant'; a.textContent='...'; box.appendChild(a); const reply = await LLMHub.roleplay(pid, msg); a.textContent = reply; box.scrollTop = box.scrollHeight; document.getElementById('rpInput').value = ''; }); document.getElementById('rpInput').addEventListener('keypress', e => { if(e.key==='Enter'&&!e.shiftKey){e.preventDefault();document.getElementById('rpSend').click();} }); // ── Coding Assistant ── let codeResult = ''; document.getElementById('codeGen').addEventListener('click', async () => { const desc = document.getElementById('codeInput').value.trim(); if(!desc) { toast('Escribe una descripcion','error'); return; } document.getElementById('codeOutput').textContent = 'Generando...'; codeResult = await LLMHub.codingAssist(desc, []); document.getElementById('codeOutput').textContent = codeResult; if (codeResult.startsWith('No hay código entrenado suficiente')) { toast(codeResult, 'error'); return; } toast('Código generado desde código entrenado localmente','success'); }); document.getElementById('codeCopy').addEventListener('click', () => { navigator.clipboard.writeText(codeResult).then(() => toast('Copiado','success')); }); document.getElementById('codePreview').addEventListener('click', () => { const m = codeResult.match(/```[a-z]*\n([\s\S]*?)```/); let html = m ? m[1] : codeResult; const frame = document.getElementById('codeFrame'); frame.style.display = 'block'; document.getElementById('codeOutput').style.display = 'none'; frame.srcdoc = `${html} `; }); // ── Characters ── document.getElementById('charBtn').addEventListener('click', async () => { const q = document.getElementById('charSearch').value; const chars = await LLMHub.searchCharacters(q, 20); document.getElementById('charGrid').innerHTML = chars.map(c => `
${c.name}
${c.desc || (c.description||'').substring(0,80)}
${(c.tags||[]).join(', ')}
` ).join(''); }); // Load on tab open document.querySelector('[data-tab="characters"]').addEventListener('click', () => { if(!document.getElementById('charGrid').innerHTML) document.getElementById('charBtn').click(); }); // ── Providers ── function renderProviders() { const providers = LLMHub.getProviders(); const active = LLMHub.getActiveProvider(); document.getElementById('providerList').innerHTML = providers.map(p => `
${p.name}
Type: ${p.type} • Models: ${p.models.join(', ')}
` ).join(''); } renderProviders(); window.renderProviders = renderProviders; // ── App Store ── function renderAppStore() { const apps = LLMHub.getStaticApps(); document.getElementById('appGrid').innerHTML = apps.map(a => `
${a.name}
${a.desc}
[${a.cat}]
` ).join(''); } renderAppStore(); console.log('[LLM Hub] Inicializado — motor WASM + 18 herramientas AI + Playground + g4f integrados'); })();