| <!DOCTYPE html> |
| <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 Together AI</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; |
| } |
| } |
| |
| |
| .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); |
| } |
| |
| |
| 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 Together AI</a |
| > |
| with <a href="https://togethet.ai/">Together AI</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> |
|
|
| |
| <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>'; |
| |
| |
| 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`; |
| }); |
| |
| |
| promptTextarea.addEventListener("keydown", (e) => { |
| if (e.key === "Enter" && !e.shiftKey) { |
| e.preventDefault(); |
| form.dispatchEvent(new Event("submit")); |
| } |
| }); |
| |
| 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; |
| |
| responseDiv.innerHTML = |
| '<div class="loading"><div class="spinner"></div></div>'; |
| const API_GATEWAY_URL = "https://einsteincoder-llm-open-connector-together.hf.space"; |
| |
| |
| 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": "Einstein1$", |
| }, |
| }); |
| |
| let content = ""; |
| |
| if (endpoint === "chat") { |
| content = response.data.choices[0].message.content; |
| } else { |
| content = response.data.choices[0].text; |
| } |
| |
| |
| const parsedContent = marked.parse(content); |
| |
| |
| responseDiv.innerHTML = parsedContent; |
| |
| |
| document.querySelectorAll("pre code").forEach((block) => { |
| hljs.highlightElement(block); |
| }); |
| } catch (error) { |
| responseDiv.textContent = "Error: " + error.message; |
| } |
| }); |
| |
| |
| hljs.highlightAll(); |
| </script> |
| </body> |
| </html> |