| <!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/client@1.2.0/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> |