Spaces:
Running on Zero
Running on Zero
Media example chips use public URLs from vl-test-suite
Browse files- app.py +7 -0
- index.html +12 -9
app.py
CHANGED
|
@@ -23,12 +23,14 @@ app = Server()
|
|
| 23 |
@spaces.GPU(size="xlarge", duration=240)
|
| 24 |
def chat(message: str,
|
| 25 |
media: FileData | None,
|
|
|
|
| 26 |
history: list,
|
| 27 |
reasoning: str) -> str:
|
| 28 |
"""Streaming multimodal chat with Muse-Glimmer-30B.
|
| 29 |
|
| 30 |
history: list of {"role": "user"|"assistant", "content": str}
|
| 31 |
media: optional image or video FileData uploaded via the Gradio client
|
|
|
|
| 32 |
"""
|
| 33 |
messages = []
|
| 34 |
for m in history:
|
|
@@ -41,6 +43,11 @@ def chat(message: str,
|
|
| 41 |
content.append({"type": "video", "path": path})
|
| 42 |
else:
|
| 43 |
content.append({"type": "image", "path": path})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
if message:
|
| 45 |
content.append({"type": "text", "text": message})
|
| 46 |
messages.append({"role": "user", "content": content})
|
|
|
|
| 23 |
@spaces.GPU(size="xlarge", duration=240)
|
| 24 |
def chat(message: str,
|
| 25 |
media: FileData | None,
|
| 26 |
+
media_url: str,
|
| 27 |
history: list,
|
| 28 |
reasoning: str) -> str:
|
| 29 |
"""Streaming multimodal chat with Muse-Glimmer-30B.
|
| 30 |
|
| 31 |
history: list of {"role": "user"|"assistant", "content": str}
|
| 32 |
media: optional image or video FileData uploaded via the Gradio client
|
| 33 |
+
media_url: optional public URL of an image or video
|
| 34 |
"""
|
| 35 |
messages = []
|
| 36 |
for m in history:
|
|
|
|
| 43 |
content.append({"type": "video", "path": path})
|
| 44 |
else:
|
| 45 |
content.append({"type": "image", "path": path})
|
| 46 |
+
elif media_url:
|
| 47 |
+
if media_url.lower().rsplit(".", 1)[-1].split("?")[0] in ("mp4", "mov", "webm", "mkv", "avi"):
|
| 48 |
+
content.append({"type": "video", "url": media_url})
|
| 49 |
+
else:
|
| 50 |
+
content.append({"type": "image", "url": media_url})
|
| 51 |
if message:
|
| 52 |
content.append({"type": "text", "text": message})
|
| 53 |
messages.append({"role": "user", "content": content})
|
index.html
CHANGED
|
@@ -161,8 +161,9 @@
|
|
| 161 |
<button class="chip" data-text="Write a short joke about saving RAM.">π Joke about RAM</button>
|
| 162 |
<button class="chip" data-text="Write a Python function to compute Fibonacci numbers with memoization.">π Fibonacci in Python</button>
|
| 163 |
<button class="chip" data-text="Explain how speculative decoding works in 3 sentences.">β‘ Speculative decoding</button>
|
| 164 |
-
<button class="chip" data-text="
|
| 165 |
-
<button class="chip" data-text="
|
|
|
|
| 166 |
</div>
|
| 167 |
<div id="chat"></div>
|
| 168 |
|
|
@@ -274,15 +275,16 @@ function setBusy(b) {
|
|
| 274 |
input.disabled = b;
|
| 275 |
}
|
| 276 |
|
| 277 |
-
async function send() {
|
| 278 |
const text = input.value.trim();
|
| 279 |
-
if (!text && !attachedFile) return;
|
| 280 |
hero.style.display = "none";
|
| 281 |
document.getElementById("examples").style.display = "none";
|
| 282 |
document.querySelector(".orb").style.padding = "12px 0 4px";
|
| 283 |
-
const isVideo = attachedFile
|
| 284 |
-
|
| 285 |
-
|
|
|
|
| 286 |
input.value = "";
|
| 287 |
input.style.height = "auto";
|
| 288 |
setBusy(true);
|
|
@@ -293,6 +295,7 @@ async function send() {
|
|
| 293 |
currentJob = client.submit("/chat", {
|
| 294 |
message: text,
|
| 295 |
media: attachedFile ? handle_file(attachedFile) : null,
|
|
|
|
| 296 |
history: history,
|
| 297 |
reasoning: document.getElementById("reasoning").value,
|
| 298 |
});
|
|
@@ -330,8 +333,8 @@ document.querySelectorAll(".chip").forEach(chip => {
|
|
| 330 |
chip.onclick = () => {
|
| 331 |
input.value = chip.dataset.text;
|
| 332 |
input.dispatchEvent(new Event("input"));
|
| 333 |
-
|
| 334 |
-
|
| 335 |
};
|
| 336 |
});
|
| 337 |
</script>
|
|
|
|
| 161 |
<button class="chip" data-text="Write a short joke about saving RAM.">π Joke about RAM</button>
|
| 162 |
<button class="chip" data-text="Write a Python function to compute Fibonacci numbers with memoization.">π Fibonacci in Python</button>
|
| 163 |
<button class="chip" data-text="Explain how speculative decoding works in 3 sentences.">β‘ Speculative decoding</button>
|
| 164 |
+
<button class="chip" data-text="What is shown in this image?" data-url="https://huggingface.co/datasets/merve/vl-test-suite/resolve/main/SF.png">π What's in this image?</button>
|
| 165 |
+
<button class="chip" data-text="Detect the bridge. Return only the detection in the model's native object-detection format, with no explanation." data-url="https://huggingface.co/datasets/merve/vl-test-suite/resolve/main/SF.png">π Detect the bridge</button>
|
| 166 |
+
<button class="chip" data-text="Describe what happens in this video." data-url="https://huggingface.co/datasets/merve/vl-test-suite/resolve/main/IMG_8137.mp4">π¬ Describe this video</button>
|
| 167 |
</div>
|
| 168 |
<div id="chat"></div>
|
| 169 |
|
|
|
|
| 275 |
input.disabled = b;
|
| 276 |
}
|
| 277 |
|
| 278 |
+
async function send(mediaUrl = null) {
|
| 279 |
const text = input.value.trim();
|
| 280 |
+
if (!text && !attachedFile && !mediaUrl) return;
|
| 281 |
hero.style.display = "none";
|
| 282 |
document.getElementById("examples").style.display = "none";
|
| 283 |
document.querySelector(".orb").style.padding = "12px 0 4px";
|
| 284 |
+
const isVideo = attachedFile ? attachedFile.type.startsWith("video/")
|
| 285 |
+
: (mediaUrl && /\.(mp4|mov|webm|mkv|avi)(\?|$)/i.test(mediaUrl));
|
| 286 |
+
const previewUrl = attachedFile ? URL.createObjectURL(attachedFile) : mediaUrl;
|
| 287 |
+
addMsg("user", text || (isVideo ? "[video]" : "[image]"), previewUrl, isVideo);
|
| 288 |
input.value = "";
|
| 289 |
input.style.height = "auto";
|
| 290 |
setBusy(true);
|
|
|
|
| 295 |
currentJob = client.submit("/chat", {
|
| 296 |
message: text,
|
| 297 |
media: attachedFile ? handle_file(attachedFile) : null,
|
| 298 |
+
media_url: attachedFile ? "" : (mediaUrl || ""),
|
| 299 |
history: history,
|
| 300 |
reasoning: document.getElementById("reasoning").value,
|
| 301 |
});
|
|
|
|
| 333 |
chip.onclick = () => {
|
| 334 |
input.value = chip.dataset.text;
|
| 335 |
input.dispatchEvent(new Event("input"));
|
| 336 |
+
if (chip.dataset.url) { send(chip.dataset.url); }
|
| 337 |
+
else input.focus();
|
| 338 |
};
|
| 339 |
});
|
| 340 |
</script>
|