<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Chat con Puter AI</title>
<script src="https://js.puter.com/v2/"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Prism.js -->
<link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-tomorrow.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-python.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-javascript.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-css.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-markup.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-json.min.js"></script>
<style>
* { box-sizing: border-box; }
body {
margin: 0;
font-family: 'Segoe UI', sans-serif;
background: #f0f0f0;
display: flex;
flex-direction: column;
height: 100vh;
}
header {
background: #4a90e2;
color: white;
padding: 15px;
text-align: center;
font-size: 20px;
font-weight: bold;
}
#chat {
flex: 1;
padding: 15px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 12px;
}
.message {
max-width: 90%;
padding: 10px 15px;
border-radius: 18px;
word-wrap: break-word;
line-height: 1.5;
white-space: pre-wrap;
}
.user {
align-self: flex-end;
background-color: #dcf8c6;
}
.bot {
align-self: flex-start;
background-color: #ffffff;
border: 1px solid #ccc;
}
footer {
padding: 10px;
background: #fff;
display: flex;
flex-direction: column;
gap: 8px;
}
#model, #prompt {
width: 100%;
padding: 10px;
font-size: 16px;
}
#sendBtn {
padding: 10px;
font-size: 16px;
background-color: #4a90e2;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
#sendBtn:disabled {
background-color: #aaa;
cursor: not-allowed;
}
pre {
position: relative;
margin-top: 10px;
border-radius: 8px;
overflow: auto;
}
.code-header {
background: #2d2d2d;
color: #fff;
padding: 5px 10px;
font-size: 12px;
display: flex;
justify-content: space-between;
align-items: center;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
.copy-btn {
background: transparent;
color: #fff;
border: none;
cursor: pointer;
font-size: 12px;
}
</style>
</head>
<body>
<header>Chat con Puter AI</header>
<div id="chat"></div>
<footer>
<select id="model">
<option value="o1">o1</option>
<option value="o1-mini">o1 mini</option>
<option value="o1-pro">o1 pro</option>
<option value="o3">o3</option>
<option value="03-mini">03 mini</option>
<option value="04-mini">04 mini</option>
<option value="gpt-4.5-preview">GPT 4.5 Preview</option>
<option value="gpt-4">gpt-4</option>
<option value="gpt-4o">gpt-4o</option>
<option value="gpt-4o-mini" selected>gpt 4o mini</option>
<option value="claude-3-7-sonnet">claude 3.7 sonnet</option>
<option value="claude-3-5-sonnet">claude 3.5 sonnet</option>
<option value="gemini-2.0-flash">gemini 2.0 flash</option>
<option value="gemini-1.5-flash">gemini 1.5 flash</option>
<option value="grok-beta">grok beta</option>
<option value="meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo">meta llama/Meta Llama 3.1 405B Instruct Turbo</option>
</select>
<textarea id="prompt" rows="2" placeholder="Escribe tu mensaje..."></textarea>
<button id="sendBtn" onclick="enviarMensaje()">Enviar</button>
</footer>
<script>
const chatContainer = document.getElementById("chat");
const promptInput = document.getElementById("prompt");
const modelSelect = document.getElementById("model");
const sendBtn = document.getElementById("sendBtn");
const history = [];
function crearBurbuja(texto, clase) {
const div = document.createElement("div");
div.className = `message ${clase}`;
div.innerText = texto;
chatContainer.appendChild(div);
chatContainer.scrollTop = chatContainer.scrollHeight;
}
function copiarCodigo(btn) {
const code = btn.closest("pre").querySelector("code");
navigator.clipboard.writeText(code.textContent).then(() => {
btn.innerText = "Copiado!";
setTimeout(() => {
btn.innerText = "Copiar";
}, 1500);
});
}
function renderizarStreaming(div, textoAcumulado) {
div.innerHTML = "";
const partes = textoAcumulado.split(/```/);
partes.forEach((parte, i) => {
if (i % 2 === 0) {
const p = document.createElement("p");
p.innerText = parte;
div.appendChild(p);
} else {
const [lenguaje, ...lineas] = parte.split('\n');
const codigo = lineas.join('\n');
const pre = document.createElement("pre");
const header = document.createElement("div");
header.className = "code-header";
header.innerHTML = `
<span>${lenguaje || 'code'}</span>
<button class="copy-btn" onclick="copiarCodigo(this)">Copiar</button>
`;
const code = document.createElement("code");
code.className = `language-${lenguaje}`;
code.textContent = codigo;
pre.appendChild(header);
pre.appendChild(code);
div.appendChild(pre);
Prism.highlightElement(code);
}
});
chatContainer.scrollTop = chatContainer.scrollHeight;
}
async function enviarMensaje() {
const prompt = promptInput.value.trim();
const model = modelSelect.value;
if (!prompt) return;
crearBurbuja(prompt, "user");
history.push({ role: "user", content: prompt });
promptInput.value = "";
sendBtn.disabled = true;
const divBot = document.createElement("div");
divBot.className = "message bot";
chatContainer.appendChild(divBot);
let textoAcumulado = "";
try {
const stream = await puter.ai.chat(history, {
stream: true,
model: model
});
for await (const part of stream) {
const texto = part?.text || "";
textoAcumulado += texto;
renderizarStreaming(divBot, textoAcumulado);
}
history.push({ role: "assistant", content: textoAcumulado });
} catch (error) {
divBot.innerText = "Error: " + error.message;
}
sendBtn.disabled = false;
}
</script>
</body>
</html>
Comentarios (0)
Inicia sesión para comentar
¡Aún no hay comentarios. Sé el primero en comentar!