Spaces:
Runtime error
Runtime error
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>LLM Open Connector Tester for GROQ</title> | |
| <link | |
| rel="icon" | |
| href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🤖</text></svg>" | |
| /> | |
| <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/highlight.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> | |
| <link | |
| rel="stylesheet" | |
| href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/styles/default.min.css" | |
| /> | |
| <link | |
| rel="stylesheet" | |
| href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" | |
| /> | |
| <style> | |
| @import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700&display=swap"); | |
| :root { | |
| --primary-color: #4a90e2; | |
| --secondary-color: #f5f5f5; | |
| --text-color: #333; | |
| --border-radius: 8px; | |
| --transition-speed: 0.3s; | |
| --charcoal: #36454f; | |
| --charcoal-light: #485a66; | |
| --charcoal-lighter: #5a6e7a; | |
| --charcoal-dark: #2c3a42; | |
| --charcoal-darker: #232e35; | |
| } | |
| body { | |
| font-family: "Open Sans", sans-serif; | |
| font-weight: 400; | |
| line-height: 1.6; | |
| color: var(--text-color); | |
| max-width: 800px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| background-color: #f0f4f8; | |
| transition: background-color var(--transition-speed) ease; | |
| } | |
| body.dark-mode { | |
| --primary-color: #64b5f6; | |
| --secondary-color: #2c2c2c; | |
| --text-color: #e0e0e0; | |
| background-color: var(--charcoal-darker); | |
| } | |
| .header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| margin-bottom: 30px; | |
| } | |
| .logo { | |
| display: flex; | |
| align-items: center; | |
| font-size: 24px; | |
| color: var(--text-color); | |
| font-weight: 600; | |
| } | |
| .logo i { | |
| margin-right: 10px; | |
| } | |
| h1 { | |
| color: var(--text-color); | |
| margin: 0; | |
| font-weight: 700; | |
| } | |
| .dark-mode-toggle { | |
| background: none; | |
| border: none; | |
| color: var(--text-color); | |
| font-size: 20px; | |
| cursor: pointer; | |
| } | |
| form { | |
| background-color: var(--secondary-color); | |
| padding: 20px; | |
| border-radius: var(--border-radius); | |
| box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); | |
| margin-bottom: 20px; | |
| } | |
| .input-container { | |
| position: relative; | |
| margin-bottom: 10px; | |
| } | |
| textarea { | |
| width: 100%; | |
| height: 120px; | |
| padding: 10px; | |
| border: 1px solid #ddd; | |
| border-radius: var(--border-radius); | |
| resize: vertical; | |
| font-size: 16px; | |
| font-family: "Open Sans", sans-serif; | |
| background-color: var(--secondary-color); | |
| color: var(--text-color); | |
| } | |
| .char-count { | |
| position: absolute; | |
| bottom: 5px; | |
| right: 10px; | |
| font-size: 12px; | |
| color: #888; | |
| } | |
| .button-container { | |
| display: flex; | |
| justify-content: space-between; | |
| } | |
| button { | |
| padding: 10px 20px; | |
| background-color: var(--primary-color); | |
| color: white; | |
| border: none; | |
| border-radius: var(--border-radius); | |
| font-size: 16px; | |
| font-family: "Open Sans", sans-serif; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: background-color var(--transition-speed) ease; | |
| } | |
| button:hover { | |
| background-color: var(--charcoal-light); | |
| } | |
| #clearButton { | |
| background-color: var(--charcoal-light); | |
| color: white; | |
| } | |
| #clearButton:hover { | |
| background-color: var(--charcoal-lighter); | |
| } | |
| #response { | |
| background-color: var(--secondary-color); | |
| padding: 20px; | |
| border-radius: var(--border-radius); | |
| box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); | |
| font-size: 16px; | |
| transition: all var(--transition-speed) ease; | |
| overflow-x: auto; | |
| min-height: 100px; | |
| line-height: 1.6; | |
| } | |
| #response h1, | |
| #response h2, | |
| #response h3, | |
| #response h4, | |
| #response h5, | |
| #response h6 { | |
| margin-top: 1.5em; | |
| margin-bottom: 0.5em; | |
| color: var(--text-color); | |
| } | |
| #response p { | |
| margin-bottom: 1em; | |
| } | |
| #response ul, | |
| #response ol { | |
| margin-bottom: 1em; | |
| padding-left: 2em; | |
| } | |
| #response li { | |
| margin-bottom: 0.5em; | |
| } | |
| #response pre { | |
| background-color: #f4f4f4; | |
| padding: 1em; | |
| border-radius: 4px; | |
| overflow-x: auto; | |
| margin-bottom: 1em; | |
| } | |
| #response code { | |
| font-family: "Courier New", Courier, monospace; | |
| font-size: 0.9em; | |
| padding: 0.2em 0.4em; | |
| background-color: #f0f0f0; | |
| border-radius: 3px; | |
| } | |
| #response pre code { | |
| padding: 0; | |
| background-color: transparent; | |
| } | |
| #response blockquote { | |
| border-left: 4px solid var(--primary-color); | |
| padding-left: 1em; | |
| margin-left: 0; | |
| margin-bottom: 1em; | |
| font-style: italic; | |
| color: #666; | |
| } | |
| #response table { | |
| border-collapse: collapse; | |
| width: 100%; | |
| margin-bottom: 1em; | |
| } | |
| #response th, | |
| #response td { | |
| border: 1px solid #ddd; | |
| padding: 8px; | |
| text-align: left; | |
| } | |
| #response th { | |
| background-color: #f4f4f4; | |
| font-weight: bold; | |
| } | |
| .default-message { | |
| color: #888; | |
| font-style: italic; | |
| } | |
| .loading { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| height: 100px; | |
| } | |
| .spinner { | |
| border: 4px solid rgba(0, 0, 0, 0.1); | |
| border-left-color: var(--primary-color); | |
| border-radius: 50%; | |
| width: 40px; | |
| height: 40px; | |
| animation: spin 1s linear infinite; | |
| } | |
| @keyframes spin { | |
| 0% { | |
| transform: rotate(0deg); | |
| } | |
| 100% { | |
| transform: rotate(360deg); | |
| } | |
| } | |
| @media (max-width: 600px) { | |
| body { | |
| padding: 10px; | |
| } | |
| } | |
| /* Styles for the endpoint selection radio buttons */ | |
| .endpoint-selection { | |
| margin-bottom: 20px; | |
| } | |
| .endpoint-selection label { | |
| margin: 0 15px; | |
| display: flex; | |
| align-items: center; | |
| font-size: 16px; | |
| color: var(--text-color); | |
| cursor: pointer; | |
| } | |
| .endpoint-selection input[type="radio"] { | |
| margin-right: 8px; | |
| accent-color: var(--primary-color); | |
| } | |
| /* Additional styles for better appearance in dark mode */ | |
| body.dark-mode .endpoint-selection input[type="radio"] { | |
| background-color: var(--secondary-color); | |
| border-color: var(--text-color); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="header"> | |
| <div class="logo"> | |
| <i class="fas fa-robot"></i> | |
| <h1>LLM Open Connector Tester</h1> | |
| </div> | |
| <button id="darkModeToggle" class="dark-mode-toggle"> | |
| <i class="fas fa-moon"></i> | |
| </button> | |
| </div> | |
| <p> | |
| Test your implementation of Salesforce’s | |
| <a | |
| href="https://github.com/salesforce/einstein-platform?tab=readme-ov-file#llm-open-connector" | |
| >LLM Open Connector For Groq</a | |
| > | |
| with <a href="https://groq.com/">Groq</a>. | |
| </p> | |
| <form id="promptForm"> | |
| <div class="input-container"> | |
| <textarea | |
| id="prompt" | |
| placeholder="Enter your prompt here..." | |
| ></textarea> | |
| <div class="char-count">0 / 500</div> | |
| </div> | |
| <!-- Endpoint Selection Radio Buttons --> | |
| <p>Endpoint to test:</p> | |
| <div class="endpoint-selection"> | |
| <label> | |
| <input type="radio" name="endpoint" value="chat" checked /> | |
| <code>/chat/completions</code> | |
| </label> | |
| <label> | |
| <input type="radio" name="endpoint" value="completion" /> | |
| <code>/completions</code> | |
| </label> | |
| </div> | |
| <div class="button-container"> | |
| <button type="submit">Generate Response</button> | |
| <button type="button" id="clearButton">Clear</button> | |
| </div> | |
| </form> | |
| <div id="response"></div> | |
| <script> | |
| const darkModeToggle = document.getElementById("darkModeToggle"); | |
| const body = document.body; | |
| const promptTextarea = document.getElementById("prompt"); | |
| const charCount = document.querySelector(".char-count"); | |
| const clearButton = document.getElementById("clearButton"); | |
| const form = document.getElementById("promptForm"); | |
| const responseDiv = document.getElementById("response"); | |
| const defaultMessage = | |
| '<div class="default-message">Your generated response will appear here. Enter a prompt above and click "Generate Response" to start.</div>'; | |
| // Set default message on page load | |
| responseDiv.innerHTML = defaultMessage; | |
| darkModeToggle.addEventListener("click", () => { | |
| body.classList.toggle("dark-mode"); | |
| darkModeToggle.innerHTML = body.classList.contains("dark-mode") | |
| ? '<i class="fas fa-sun"></i>' | |
| : '<i class="fas fa-moon"></i>'; | |
| }); | |
| promptTextarea.addEventListener("input", () => { | |
| const length = promptTextarea.value.length; | |
| charCount.textContent = `${length} / 500`; | |
| }); | |
| // Add event listener for Enter key | |
| promptTextarea.addEventListener("keydown", (e) => { | |
| if (e.key === "Enter" && !e.shiftKey) { | |
| e.preventDefault(); // Prevent default behavior (newline) | |
| form.dispatchEvent(new Event("submit")); // Trigger form submission | |
| } | |
| }); | |
| clearButton.addEventListener("click", () => { | |
| promptTextarea.value = ""; | |
| responseDiv.innerHTML = defaultMessage; | |
| charCount.textContent = "0 / 500"; | |
| }); | |
| form.addEventListener("submit", async (e) => { | |
| e.preventDefault(); | |
| const prompt = promptTextarea.value.trim(); | |
| if (!prompt) return; // Don't submit if the prompt is empty | |
| responseDiv.innerHTML = | |
| '<div class="loading"><div class="spinner"></div></div>'; | |
| const API_GATEWAY_URL = "https://einsteincoder-llm-open-connector-groq.hf.space"; | |
| // Get the selected endpoint | |
| const endpoint = document.querySelector( | |
| 'input[name="endpoint"]:checked' | |
| ).value; | |
| let url = ""; | |
| let data = {}; | |
| if (endpoint === "chat") { | |
| url = `${API_GATEWAY_URL}/chat/completions`; | |
| data = { | |
| messages: [{ role: "user", content: prompt }], | |
| temperature: 0.5, | |
| max_tokens: 1000, | |
| }; | |
| } else { | |
| url = `${API_GATEWAY_URL}/completions`; | |
| data = { | |
| prompt: prompt, | |
| temperature: 0.5, | |
| max_tokens: 1000, | |
| }; | |
| } | |
| try { | |
| const response = await axios.post(url, data, { | |
| headers: { | |
| "api-key": "Einstein1234$", | |
| }, | |
| }); | |
| let content = ""; | |
| if (endpoint === "chat") { | |
| content = response.data.choices[0].message.content; | |
| } else { | |
| content = response.data.choices[0].text; | |
| } | |
| // Parse the Markdown content | |
| const parsedContent = marked.parse(content); | |
| // Set the parsed content to the response div | |
| responseDiv.innerHTML = parsedContent; | |
| // Highlight code blocks | |
| document.querySelectorAll("pre code").forEach((block) => { | |
| hljs.highlightElement(block); | |
| }); | |
| } catch (error) { | |
| responseDiv.textContent = "Error: " + error.message; | |
| } | |
| }); | |
| // Initialize highlight.js | |
| hljs.highlightAll(); | |
| </script> | |
| </body> | |
| </html> |