Spaces:
Running
Running
muralipala1504 commited on
Commit ·
06fa89e
1
Parent(s): d03090c
Add copy button, update to llama-3.3-70b, remove unused main.py
Browse files- app.js +64 -10
- index.html +24 -0
app.js
CHANGED
|
@@ -1,8 +1,4 @@
|
|
| 1 |
-
// Plain Vanilla Chat Frontend
|
| 2 |
-
// - One textarea, one Send button, one output area
|
| 3 |
-
// - POSTs to /chat/run-agent with { prompt }
|
| 4 |
-
// - Renders answer or error; optional Markdown if window.marked is available
|
| 5 |
-
|
| 6 |
(function () {
|
| 7 |
"use strict";
|
| 8 |
|
|
@@ -22,6 +18,38 @@
|
|
| 22 |
return `<pre>${escapeHtml(md)}</pre>`;
|
| 23 |
}
|
| 24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
function appendMessage(container, sender, message, useMarkdown = false) {
|
| 26 |
const msgDiv = document.createElement("div");
|
| 27 |
msgDiv.classList.add("message");
|
|
@@ -34,12 +62,39 @@
|
|
| 34 |
if (codeBlockMatch) {
|
| 35 |
const lang = codeBlockMatch[1] || "bash";
|
| 36 |
const code = codeBlockMatch[2];
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
} else if (useMarkdown) {
|
| 42 |
msgDiv.innerHTML = `<strong>${sender}:</strong>${renderMarkdown(String(message))}`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
} else {
|
| 44 |
msgDiv.innerHTML = `<strong>${sender}:</strong> <pre>${escapeHtml(String(message))}</pre>`;
|
| 45 |
}
|
|
@@ -76,7 +131,6 @@
|
|
| 76 |
body: JSON.stringify({ prompt }),
|
| 77 |
});
|
| 78 |
|
| 79 |
-
// Try JSON; if it fails, show raw text to help debugging
|
| 80 |
let data = null;
|
| 81 |
let rawText = "";
|
| 82 |
try {
|
|
|
|
| 1 |
+
// Plain Vanilla Chat Frontend with Copy Button
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
(function () {
|
| 3 |
"use strict";
|
| 4 |
|
|
|
|
| 18 |
return `<pre>${escapeHtml(md)}</pre>`;
|
| 19 |
}
|
| 20 |
|
| 21 |
+
function createCopyButton(code) {
|
| 22 |
+
const btn = document.createElement("button");
|
| 23 |
+
btn.className = "copy-btn";
|
| 24 |
+
btn.textContent = "Copy";
|
| 25 |
+
btn.onclick = async () => {
|
| 26 |
+
try {
|
| 27 |
+
// Try modern clipboard API first
|
| 28 |
+
await navigator.clipboard.writeText(code);
|
| 29 |
+
btn.textContent = "Copied!";
|
| 30 |
+
setTimeout(() => { btn.textContent = "Copy"; }, 2000);
|
| 31 |
+
} catch (err) {
|
| 32 |
+
// Fallback for non-secure contexts
|
| 33 |
+
const textarea = document.createElement("textarea");
|
| 34 |
+
textarea.value = code;
|
| 35 |
+
textarea.style.position = "fixed";
|
| 36 |
+
textarea.style.opacity = "0";
|
| 37 |
+
document.body.appendChild(textarea);
|
| 38 |
+
textarea.select();
|
| 39 |
+
try {
|
| 40 |
+
document.execCommand("copy");
|
| 41 |
+
btn.textContent = "Copied!";
|
| 42 |
+
setTimeout(() => { btn.textContent = "Copy"; }, 2000);
|
| 43 |
+
} catch (e) {
|
| 44 |
+
btn.textContent = "Failed";
|
| 45 |
+
setTimeout(() => { btn.textContent = "Copy"; }, 2000);
|
| 46 |
+
}
|
| 47 |
+
document.body.removeChild(textarea);
|
| 48 |
+
}
|
| 49 |
+
};
|
| 50 |
+
return btn;
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
function appendMessage(container, sender, message, useMarkdown = false) {
|
| 54 |
const msgDiv = document.createElement("div");
|
| 55 |
msgDiv.classList.add("message");
|
|
|
|
| 62 |
if (codeBlockMatch) {
|
| 63 |
const lang = codeBlockMatch[1] || "bash";
|
| 64 |
const code = codeBlockMatch[2];
|
| 65 |
+
|
| 66 |
+
const codeWrapper = document.createElement("div");
|
| 67 |
+
codeWrapper.className = "code-wrapper";
|
| 68 |
+
|
| 69 |
+
const pre = document.createElement("pre");
|
| 70 |
+
const codeEl = document.createElement("code");
|
| 71 |
+
codeEl.className = `language-${lang}`;
|
| 72 |
+
codeEl.textContent = code;
|
| 73 |
+
pre.appendChild(codeEl);
|
| 74 |
+
|
| 75 |
+
const copyBtn = createCopyButton(code);
|
| 76 |
+
|
| 77 |
+
codeWrapper.appendChild(copyBtn);
|
| 78 |
+
codeWrapper.appendChild(pre);
|
| 79 |
+
|
| 80 |
+
msgDiv.innerHTML = `<strong>${sender}:</strong>`;
|
| 81 |
+
msgDiv.appendChild(codeWrapper);
|
| 82 |
} else if (useMarkdown) {
|
| 83 |
msgDiv.innerHTML = `<strong>${sender}:</strong>${renderMarkdown(String(message))}`;
|
| 84 |
+
|
| 85 |
+
// Add copy buttons to any code blocks in markdown
|
| 86 |
+
msgDiv.querySelectorAll("pre code").forEach((codeEl) => {
|
| 87 |
+
const code = codeEl.textContent;
|
| 88 |
+
const pre = codeEl.parentElement;
|
| 89 |
+
const wrapper = document.createElement("div");
|
| 90 |
+
wrapper.className = "code-wrapper";
|
| 91 |
+
|
| 92 |
+
const copyBtn = createCopyButton(code);
|
| 93 |
+
|
| 94 |
+
pre.parentNode.insertBefore(wrapper, pre);
|
| 95 |
+
wrapper.appendChild(copyBtn);
|
| 96 |
+
wrapper.appendChild(pre);
|
| 97 |
+
});
|
| 98 |
} else {
|
| 99 |
msgDiv.innerHTML = `<strong>${sender}:</strong> <pre>${escapeHtml(String(message))}</pre>`;
|
| 100 |
}
|
|
|
|
| 131 |
body: JSON.stringify({ prompt }),
|
| 132 |
});
|
| 133 |
|
|
|
|
| 134 |
let data = null;
|
| 135 |
let rawText = "";
|
| 136 |
try {
|
index.html
CHANGED
|
@@ -122,6 +122,30 @@
|
|
| 122 |
}
|
| 123 |
a { color: var(--accent); text-decoration: none; }
|
| 124 |
a:hover { text-decoration: underline; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
</style>
|
| 126 |
</head>
|
| 127 |
<body>
|
|
|
|
| 122 |
}
|
| 123 |
a { color: var(--accent); text-decoration: none; }
|
| 124 |
a:hover { text-decoration: underline; }
|
| 125 |
+
|
| 126 |
+
/* Copy button styles */
|
| 127 |
+
.code-wrapper {
|
| 128 |
+
position: relative;
|
| 129 |
+
margin: 6px 0 0;
|
| 130 |
+
}
|
| 131 |
+
.copy-btn {
|
| 132 |
+
position: absolute;
|
| 133 |
+
top: 8px;
|
| 134 |
+
right: 8px;
|
| 135 |
+
padding: 4px 10px;
|
| 136 |
+
font-size: 11px;
|
| 137 |
+
background: #1e293b;
|
| 138 |
+
color: var(--text);
|
| 139 |
+
border: 1px solid var(--border);
|
| 140 |
+
border-radius: 4px;
|
| 141 |
+
cursor: pointer;
|
| 142 |
+
z-index: 10;
|
| 143 |
+
font-weight: 600;
|
| 144 |
+
}
|
| 145 |
+
.copy-btn:hover {
|
| 146 |
+
background: #334155;
|
| 147 |
+
border-color: #475569;
|
| 148 |
+
}
|
| 149 |
</style>
|
| 150 |
</head>
|
| 151 |
<body>
|