|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Compliment Bot π</title> |
|
|
|
<style> |
|
body { |
|
font-family: Arial, sans-serif; |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
height: 100vh; |
|
margin: 0; |
|
background-color: #f0f0f0; |
|
} |
|
.container { |
|
text-align: center; |
|
background-color: white; |
|
padding: 20px; |
|
border-radius: 10px; |
|
box-shadow: 0 0 10px rgba(0,0,0,0.1); |
|
max-width: 400px; |
|
width: 100%; |
|
} |
|
#headshot { |
|
max-width: 300px; |
|
max-height: 300px; |
|
margin: 20px auto; |
|
display: block; |
|
} |
|
#compliment { |
|
font-size: 18px; |
|
font-weight: bold; |
|
color: #4a4a4a; |
|
min-height: 50px; |
|
} |
|
.loader { |
|
border: 5px solid #f3f3f3; |
|
border-top: 5px solid #3498db; |
|
border-radius: 50%; |
|
width: 30px; |
|
height: 30px; |
|
animation: spin 1s linear infinite; |
|
margin: 20px auto; |
|
display: none; |
|
} |
|
@keyframes spin { |
|
0% { transform: rotate(0deg); } |
|
100% { transform: rotate(360deg); } |
|
} |
|
#uploadButton { |
|
background-color: #4CAF50; |
|
border: none; |
|
color: white; |
|
padding: 10px 20px; |
|
text-align: center; |
|
text-decoration: none; |
|
display: inline-block; |
|
font-size: 16px; |
|
margin: 4px 2px; |
|
cursor: pointer; |
|
border-radius: 5px; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div class="container"> |
|
<h1> Compliment Bot π</h1> |
|
<input type="file" id="fileInput" accept="image/*" style="display: none;"> |
|
<button id="uploadButton">Upload New Headshot</button> |
|
<br><br> |
|
<img id="headshot" src="" alt="Your headshot" style="display:none;"> |
|
<div class="loader" id="loader"></div> |
|
<p id="compliment"></p> |
|
</div> |
|
|
|
<script> |
|
const fileInput = document.getElementById('fileInput'); |
|
const uploadButton = document.getElementById('uploadButton'); |
|
const headshot = document.getElementById('headshot'); |
|
const compliment = document.getElementById('compliment'); |
|
const loader = document.getElementById('loader'); |
|
|
|
const SYSTEM_PROMPT = ` |
|
You are helpful assistant that gives the best compliments to people. |
|
You will be given a caption of someone's headshot. |
|
Based on that caption, provide a one sentence compliment to the person in the image. |
|
Make sure you compliment the person in the image and not any objects or scenery. |
|
Do NOT include any hashtags in your compliment or phrases like (emojis: dog, smiling face with heart-eyes, sun). |
|
|
|
Here are some examples of the desired behavior: |
|
|
|
Caption: a front view of a man who is smiling, there is a lighthouse in the background, there is a grassy area on the left that is green and curved. in the distance you can see the ocean and the shore. there is a grey and cloudy sky above the lighthouse and the trees. |
|
Compliment: Your smile is as bright as a lighthouse, lighting up the world around you. π |
|
|
|
Caption: in a close-up, a blonde woman with short, wavy hair, is the focal point of the image. she's dressed in a dark brown turtleneck sweater, paired with a black hat and a black suit jacket. her lips are a vibrant red, and her eyes are a deep brown. in the background, a man with a black hat and a white shirt is visible. |
|
Compliment: You are the epitome of elegance and grace, with a style that is as timeless as your beauty. ππ© |
|
|
|
Conversation begins below: |
|
|
|
` |
|
|
|
uploadButton.addEventListener('click', function() { |
|
fileInput.click(); |
|
}); |
|
|
|
fileInput.addEventListener('change', function(e) { |
|
const file = e.target.files[0]; |
|
if (file) { |
|
const reader = new FileReader(); |
|
reader.onload = function(event) { |
|
headshot.src = event.target.result; |
|
headshot.style.display = 'block'; |
|
generateCompliment(file); |
|
} |
|
reader.readAsDataURL(file); |
|
} |
|
}); |
|
|
|
async function generateCompliment(file) { |
|
compliment.textContent = ''; |
|
loader.style.display = 'block'; |
|
|
|
try { |
|
const client_lib = await import("https://cdn.jsdelivr.net/npm/@gradio/[email protected]/dist/index.min.js"); |
|
const Client = client_lib.Client; |
|
const handle_file = client_lib.handle_file; |
|
const captioning_space = await Client.connect("gokaygokay/SD3-Long-Captioner"); |
|
const llm_space = await Client.connect("hysts/zephyr-7b"); |
|
|
|
const caption = await captioning_space.predict("/create_captions_rich", { image: file }); |
|
|
|
|
|
console.info("Caption", caption.data); |
|
|
|
const submission = llm_space.submit("/chat", { |
|
system_prompt: SYSTEM_PROMPT, |
|
message: `Caption: ${caption.data}\nCompliment: `, |
|
max_new_tokens: 256, |
|
temperature: 0.7, |
|
top_p: 0.95, |
|
top_k: 50, |
|
repetition_penalty: 1, |
|
} |
|
) |
|
|
|
for await (const msg of submission) { |
|
loader.style.display = 'none'; |
|
if (msg.type === "data") { |
|
console.log("msg.data", msg.data); |
|
compliment.textContent = msg.data[0] |
|
} |
|
} |
|
} catch (error) { |
|
console.error('Error:', error); |
|
loader.style.display = 'none'; |
|
compliment.textContent = "Oops! We couldn't generate a compliment. You're still awesome though!" |
|
} |
|
|
|
} |
|
</script> |
|
</body> |
|
</html> |