EinsteinCoder/llm-open-connector-together
0
1<!DOCTYPE html>2<html lang="en">3 <head>4 <meta charset="UTF-8" />5 <meta name="viewport" content="width=device-width, initial-scale=1.0" />6 <title>LLM Open Connector Tester for Together AI</title>7 <link8 rel="icon"9 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>"10 />11 <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>12 <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/highlight.min.js"></script>13 <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>14 <link15 rel="stylesheet"16 href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/styles/default.min.css"17 />18 <link19 rel="stylesheet"20 href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"21 />22 <style>23 @import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700&display=swap");24 25 :root {26 --primary-color: #4a90e2;27 --secondary-color: #f5f5f5;28 --text-color: #333;29 --border-radius: 8px;30 --transition-speed: 0.3s;31 --charcoal: #36454f;32 --charcoal-light: #485a66;33 --charcoal-lighter: #5a6e7a;34 --charcoal-dark: #2c3a42;35 --charcoal-darker: #232e35;36 }37 38 body {39 font-family: "Open Sans", sans-serif;40 font-weight: 400;41 line-height: 1.6;42 color: var(--text-color);43 max-width: 800px;44 margin: 0 auto;45 padding: 20px;46 background-color: #f0f4f8;47 transition: background-color var(--transition-speed) ease;48 }49 50 body.dark-mode {51 --primary-color: #64b5f6;52 --secondary-color: #2c2c2c;53 --text-color: #e0e0e0;54 background-color: var(--charcoal-darker);55 }56 57 .header {58 display: flex;59 align-items: center;60 justify-content: space-between;61 margin-bottom: 30px;62 }63 64 .logo {65 display: flex;66 align-items: center;67 font-size: 24px;68 color: var(--text-color);69 font-weight: 600;70 }71 72 .logo i {73 margin-right: 10px;74 }75 76 h1 {77 color: var(--text-color);78 margin: 0;79 font-weight: 700;80 }81 82 .dark-mode-toggle {83 background: none;84 border: none;85 color: var(--text-color);86 font-size: 20px;87 cursor: pointer;88 }89 90 form {91 background-color: var(--secondary-color);92 padding: 20px;93 border-radius: var(--border-radius);94 box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);95 margin-bottom: 20px;96 }97 98 .input-container {99 position: relative;100 margin-bottom: 10px;101 }102 103 textarea {104 width: 100%;105 height: 120px;106 padding: 10px;107 border: 1px solid #ddd;108 border-radius: var(--border-radius);109 resize: vertical;110 font-size: 16px;111 font-family: "Open Sans", sans-serif;112 background-color: var(--secondary-color);113 color: var(--text-color);114 }115 116 .char-count {117 position: absolute;118 bottom: 5px;119 right: 10px;120 font-size: 12px;121 color: #888;122 }123 124 .button-container {125 display: flex;126 justify-content: space-between;127 }128 129 button {130 padding: 10px 20px;131 background-color: var(--primary-color);132 color: white;133 border: none;134 border-radius: var(--border-radius);135 font-size: 16px;136 font-family: "Open Sans", sans-serif;137 font-weight: 600;138 cursor: pointer;139 transition: background-color var(--transition-speed) ease;140 }141 142 button:hover {143 background-color: var(--charcoal-light);144 }145 146 #clearButton {147 background-color: var(--charcoal-light);148 color: white;149 }150 151 #clearButton:hover {152 background-color: var(--charcoal-lighter);153 }154 155 #response {156 background-color: var(--secondary-color);157 padding: 20px;158 border-radius: var(--border-radius);159 box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);160 font-size: 16px;161 transition: all var(--transition-speed) ease;162 overflow-x: auto;163 min-height: 100px;164 line-height: 1.6;165 }166 167 #response h1,168 #response h2,169 #response h3,170 #response h4,171 #response h5,172 #response h6 {173 margin-top: 1.5em;174 margin-bottom: 0.5em;175 color: var(--text-color);176 }177 178 #response p {179 margin-bottom: 1em;180 }181 182 #response ul,183 #response ol {184 margin-bottom: 1em;185 padding-left: 2em;186 }187 188 #response li {189 margin-bottom: 0.5em;190 }191 192 #response pre {193 background-color: #f4f4f4;194 padding: 1em;195 border-radius: 4px;196 overflow-x: auto;197 margin-bottom: 1em;198 }199 200 #response code {201 font-family: "Courier New", Courier, monospace;202 font-size: 0.9em;203 padding: 0.2em 0.4em;204 background-color: #f0f0f0;205 border-radius: 3px;206 }207 208 #response pre code {209 padding: 0;210 background-color: transparent;211 }212 213 #response blockquote {214 border-left: 4px solid var(--primary-color);215 padding-left: 1em;216 margin-left: 0;217 margin-bottom: 1em;218 font-style: italic;219 color: #666;220 }221 222 #response table {223 border-collapse: collapse;224 width: 100%;225 margin-bottom: 1em;226 }227 228 #response th,229 #response td {230 border: 1px solid #ddd;231 padding: 8px;232 text-align: left;233 }234 235 #response th {236 background-color: #f4f4f4;237 font-weight: bold;238 }239 240 .default-message {241 color: #888;242 font-style: italic;243 }244 245 .loading {246 display: flex;247 justify-content: center;248 align-items: center;249 height: 100px;250 }251 252 .spinner {253 border: 4px solid rgba(0, 0, 0, 0.1);254 border-left-color: var(--primary-color);255 border-radius: 50%;256 width: 40px;257 height: 40px;258 animation: spin 1s linear infinite;259 }260 261 @keyframes spin {262 0% {263 transform: rotate(0deg);264 }265 100% {266 transform: rotate(360deg);267 }268 }269 270 @media (max-width: 600px) {271 body {272 padding: 10px;273 }274 }275 276 /* Styles for the endpoint selection radio buttons */277 .endpoint-selection {278 margin-bottom: 20px;279 }280 281 .endpoint-selection label {282 margin: 0 15px;283 display: flex;284 align-items: center;285 font-size: 16px;286 color: var(--text-color);287 cursor: pointer;288 }289 290 .endpoint-selection input[type="radio"] {291 margin-right: 8px;292 accent-color: var(--primary-color);293 }294 295 /* Additional styles for better appearance in dark mode */296 body.dark-mode .endpoint-selection input[type="radio"] {297 background-color: var(--secondary-color);298 border-color: var(--text-color);299 }300 </style>301 </head>302 <body>303 <div class="header">304 <div class="logo">305 <i class="fas fa-robot"></i>306 <h1>LLM Open Connector Tester</h1>307 </div>308 309 <button id="darkModeToggle" class="dark-mode-toggle">310 <i class="fas fa-moon"></i>311 </button>312 </div>313 314 <p>315 Test your implementation of Salesforce’s316 <a317 href="https://github.com/salesforce/einstein-platform?tab=readme-ov-file#llm-open-connector"318 >LLM Open Connector For Together AI</a319 >320 with <a href="https://togethet.ai/">Together AI</a>.321 </p>322 323 <form id="promptForm">324 <div class="input-container">325 <textarea326 id="prompt"327 placeholder="Enter your prompt here..."328 ></textarea>329 <div class="char-count">0 / 500</div>330 </div>331 332 <!-- Endpoint Selection Radio Buttons -->333 <p>Endpoint to test:</p>334 335 <div class="endpoint-selection">336 <label>337 <input type="radio" name="endpoint" value="chat" checked />338 <code>/chat/completions</code>339 </label>340 <label>341 <input type="radio" name="endpoint" value="completion" />342 <code>/completions</code>343 </label>344 </div>345 346 <div class="button-container">347 <button type="submit">Generate Response</button>348 <button type="button" id="clearButton">Clear</button>349 </div>350 </form>351 <div id="response"></div>352 353 <script>354 const darkModeToggle = document.getElementById("darkModeToggle");355 const body = document.body;356 const promptTextarea = document.getElementById("prompt");357 const charCount = document.querySelector(".char-count");358 const clearButton = document.getElementById("clearButton");359 const form = document.getElementById("promptForm");360 const responseDiv = document.getElementById("response");361 const defaultMessage =362 '<div class="default-message">Your generated response will appear here. Enter a prompt above and click "Generate Response" to start.</div>';363 364 // Set default message on page load365 responseDiv.innerHTML = defaultMessage;366 367 darkModeToggle.addEventListener("click", () => {368 body.classList.toggle("dark-mode");369 darkModeToggle.innerHTML = body.classList.contains("dark-mode")370 ? '<i class="fas fa-sun"></i>'371 : '<i class="fas fa-moon"></i>';372 });373 374 promptTextarea.addEventListener("input", () => {375 const length = promptTextarea.value.length;376 charCount.textContent = `${length} / 500`;377 });378 379 // Add event listener for Enter key380 promptTextarea.addEventListener("keydown", (e) => {381 if (e.key === "Enter" && !e.shiftKey) {382 e.preventDefault(); // Prevent default behavior (newline)383 form.dispatchEvent(new Event("submit")); // Trigger form submission384 }385 });386 387 clearButton.addEventListener("click", () => {388 promptTextarea.value = "";389 responseDiv.innerHTML = defaultMessage;390 charCount.textContent = "0 / 500";391 });392 393 form.addEventListener("submit", async (e) => {394 e.preventDefault();395 const prompt = promptTextarea.value.trim();396 if (!prompt) return; // Don't submit if the prompt is empty397 398 responseDiv.innerHTML =399 '<div class="loading"><div class="spinner"></div></div>';400 const API_GATEWAY_URL = "https://einsteincoder-llm-open-connector-together.hf.space";401 402 // Get the selected endpoint403 const endpoint = document.querySelector(404 'input[name="endpoint"]:checked'405 ).value;406 407 let url = "";408 let data = {};409 410 if (endpoint === "chat") {411 url = `${API_GATEWAY_URL}/chat/completions`;412 data = {413 messages: [{ role: "user", content: prompt }],414 temperature: 0.5,415 max_tokens: 1000,416 };417 } else {418 url = `${API_GATEWAY_URL}/completions`;419 data = {420 prompt: prompt,421 temperature: 0.5,422 max_tokens: 1000,423 };424 }425 426 try {427 const response = await axios.post(url, data, {428 headers: {429 "api-key": "Einstein1$",430 },431 });432 433 let content = "";434 435 if (endpoint === "chat") {436 content = response.data.choices[0].message.content;437 } else {438 content = response.data.choices[0].text;439 }440 441 // Parse the Markdown content442 const parsedContent = marked.parse(content);443 444 // Set the parsed content to the response div445 responseDiv.innerHTML = parsedContent;446 447 // Highlight code blocks448 document.querySelectorAll("pre code").forEach((block) => {449 hljs.highlightElement(block);450 });451 } catch (error) {452 responseDiv.textContent = "Error: " + error.message;453 }454 });455 456 // Initialize highlight.js457 hljs.highlightAll();458 </script>459 </body>460</html>