Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 101 additions & 67 deletions 04-chatgpt-local/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@
border-radius: 50%;
animation: loadingspin 1s linear infinite;
}

h4 {
}
h4 {
color: #444;
margin-bottom: 8px;
}
Expand All @@ -157,7 +157,6 @@
font-size: 10px;
opacity: .4;
}
}

@keyframes loadingspin {
100% {
Expand All @@ -178,80 +177,106 @@

// pongo delante de la variable un símbolo de $
// para indicar que es un elemento del DOM
const $form = $('form')
const $input = $('input')
const $form = $('.userForm')
const $input = $('.userInput')
const $template = $('#message-template')
const $messages = $('ul')
const $container = $('main')
const $button = $('button')
const $info = $('small')
const $button = $('.send')
const $info = $('.info')
const $loading = $('.loading')

let messages = []
let end = false

const SELECTED_MODEL = 'Llama-3-8B-Instruct-q4f32_1-MLC-1k'

const engine = await CreateWebWorkerMLCEngine(
new Worker('./worker.js', { type: 'module' }),
SELECTED_MODEL,
{
initProgressCallback: (info) => {
$info.textContent = info.text
if (info.progress === 1 && !end) {
end = true
$loading?.parentNode?.removeChild($loading)
$button.removeAttribute('disabled')
addMessage("¡Hola! Soy un ChatGPT que se ejecuta completamente en tu navegador. ¿En qué puedo ayudarte hoy?", 'bot')
$input.focus()
const $model = $(".selectedModel");
const $modelForm = $(".model");
const $select = $(".modelButton");
const $loadingText1 = $("#loadingText1")
const $loadingText2 = $("#loadingText2")
const $loadingBar = $("#loadingBar")
const $defaultModel = $("#defaultModel")
const $modelWarn = $("#modelWarn")


let SELECTED_MODEL


$modelForm.addEventListener("submit", async (e) => {
e.preventDefault()
const model = $model.value.trim();
if (model != "") {
SELECTED_MODEL = model
} else {
SELECTED_MODEL = "Llama-3-8B-Instruct-q4f32_1-MLC-1k"
}
$select.setAttribute('disabled', '')
let messages = []
let end = false

$loadingText1.removeAttribute("hidden", "")
$loadingText2.removeAttribute("hidden", "")
$loadingBar.removeAttribute("hidden", "")
$modelWarn.setAttribute("hidden", "")
$defaultModel.setAttribute("hidden", "")

const engine = await CreateWebWorkerMLCEngine(
new Worker('./worker.js', { type: 'module' }),
SELECTED_MODEL,
{
initProgressCallback: (info) => {
$info.textContent = info.text
if (info.progress === 1 && !end) {
end = true
$loading?.parentNode?.removeChild($loading)
$button.removeAttribute('disabled')
addMessage("¡Hola! Soy un ChatGPT que se ejecuta completamente en tu navegador. ¿En qué puedo ayudarte hoy?", 'bot')
$input.focus()
}
}
}
}
)
)

$form.addEventListener('submit', async (event) => {
event.preventDefault()
const messageText = $input.value.trim()

if (messageText !== '') {
// añadimos el mensaje en el DOM
$input.value = ''
}
$form.addEventListener('submit', async (event) => {
event.preventDefault()
const messageText = $input.value.trim()

addMessage(messageText, 'user')
$button.setAttribute('disabled', '')
if (messageText !== '') {
// añadimos el mensaje en el DOM
$input.value = ''
}

const userMessage = {
role: 'user',
content: messageText
}
addMessage(messageText, 'user')
$button.setAttribute('disabled', '')

messages.push(userMessage)
const userMessage = {
role: 'user',
content: messageText
}

const chunks = await engine.chat.completions.create({
messages,
stream: true
})
messages.push(userMessage)

let reply = ""
const chunks = await engine.chat.completions.create({
messages,
stream: true
})

const $botMessage = addMessage("", 'bot')
let reply = ""

for await (const chunk of chunks) {
const choice = chunk.choices[0]
const content = choice?.delta?.content ?? ""
reply += content
$botMessage.textContent = reply
}
const $botMessage = addMessage("", 'bot')

$button.removeAttribute('disabled')
messages.push({
role: 'assistant',
content: reply
})
$container.scrollTop = $container.scrollHeight
})
for await (const chunk of chunks) {
const choice = chunk.choices[0]
const content = choice?.delta?.content ?? ""
reply += content
$botMessage.textContent = reply
}

$button.removeAttribute('disabled')
messages.push({
role: 'assistant',
content: reply
})
$container.scrollTop = $container.scrollHeight
})
})
function addMessage(text, sender) {
// clonar el template
const clonedTemplate = $template.content.cloneNode(true)
Expand All @@ -275,21 +300,30 @@

<body>
<main>
<form class="model">
<input placeholder="Select model" class="selectedModel" />
<button class="modelButton">Elegir</button>
</form>
<ul>
<li>
<h4 id="modelWarn">Selecciona un modelo para continuar</h4>
<h5 id="defaultModel">Modelo por defecto: Llama-3-8B-Instruct-q4f32_1-MLC-1k (pulsa "Elegir")</h5>
</li>
<ul>
<li class="loading">
<i></i>
<h4>Cargando...</h4>
<h5>Esto puede tardar un poco. Paciencia.</h5>
<i id="loadingBar" hidden></i>
<h4 id="loadingText1" hidden>Cargando...</h4>
<h5 id="loadingText2" hidden>Esto puede tardar un poco. Paciencia.</h5>
</li>
</ul>
</main>

<form>
<input placeholder="Escribe tu mensaje aquí...">
<button disabled>Enviar</button>
<form class="userForm">
<input class="userInput" placeholder="Escribe tu mensaje aquí...">
<button disabled class="send">Enviar</button>
</form>

<small>&nbsp;</small>
<small class="info">&nbsp;</small>

<template id="message-template">
<li class="message">
Expand Down