akhaliq HF Staff commited on
Commit
00d07aa
·
1 Parent(s): bed9a72

Show reasoning in collapsible block; simplify header nav

Browse files
Files changed (2) hide show
  1. app.py +1 -7
  2. index.html +39 -8
app.py CHANGED
@@ -71,13 +71,7 @@ def chat(message: str,
71
  reply = ""
72
  for token in streamer:
73
  reply += token
74
- # Model may emit a reasoning preamble ending with an
75
- # "assistant to=user" marker before the final response.
76
- if "to=user" in reply:
77
- final = reply.rsplit("to=user", 1)[1].strip()
78
- else:
79
- final = ""
80
- yield final if final else "💭 thinking…"
81
  thread.join()
82
 
83
 
 
71
  reply = ""
72
  for token in streamer:
73
  reply += token
74
+ yield reply # raw stream; frontend splits reasoning from final reply
 
 
 
 
 
 
75
  thread.join()
76
 
77
 
index.html CHANGED
@@ -63,6 +63,9 @@
63
  .bot { align-self: flex-start; background: var(--card); border: 1px solid var(--border); color: #eef2fb; border-bottom-left-radius: 6px; }
64
  .msg img { max-width: 240px; border-radius: 12px; display: block; margin-bottom: 8px; }
65
  .sys { align-self: center; color: var(--muted); font-size: 12px; background: none; }
 
 
 
66
  .bot.typing span::after { content: "▊"; animation: blink 1s steps(1) infinite; color: #8ab4ff; }
67
  @keyframes blink { 50% { opacity: 0; } }
68
 
@@ -121,10 +124,7 @@
121
  </div>
122
  <nav>
123
  <a href="https://huggingface.co/meta-models/Muse-Glimmer-30B" target="_blank">Model Card</a>
124
- <a href="https://arxiv.org/abs/2602.06036" target="_blank">DFlash Paper</a>
125
- <a href="https://arxiv.org/abs/2504.13181" target="_blank">Perception Encoder</a>
126
  </nav>
127
- <button class="cta" onclick="document.getElementById('input').focus()">Try Muse Glimmer</button>
128
  </header>
129
 
130
  <div class="orb">
@@ -216,6 +216,37 @@ function addMsg(role, text, imgUrl) {
216
  return t;
217
  }
218
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  function setBusy(b) {
220
  sendBtn.style.display = b ? "none" : "";
221
  stopBtn.style.display = b ? "" : "none";
@@ -233,8 +264,8 @@ async function send() {
233
  input.style.height = "auto";
234
  setBusy(true);
235
 
236
- const botSpan = addMsg("bot", "");
237
- botSpan.parentElement.classList.add("typing");
238
  try {
239
  currentJob = client.submit("/chat", {
240
  message: text,
@@ -251,16 +282,16 @@ async function send() {
251
  }
252
  if (event.type === "data") {
253
  finalText = event.data[0];
254
- botSpan.textContent = finalText;
255
  chatEl.scrollTop = chatEl.scrollHeight;
256
  }
257
  }
258
  history.push({ role: "user", content: text || "[image]" });
259
  history.push({ role: "assistant", content: finalText });
260
  } catch (e) {
261
- botSpan.textContent = "⚠️ " + (e.message || e);
262
  } finally {
263
- botSpan.parentElement.classList.remove("typing");
264
  setBusy(false);
265
  clearImage();
266
  queueEl.textContent = "—";
 
63
  .bot { align-self: flex-start; background: var(--card); border: 1px solid var(--border); color: #eef2fb; border-bottom-left-radius: 6px; }
64
  .msg img { max-width: 240px; border-radius: 12px; display: block; margin-bottom: 8px; }
65
  .sys { align-self: center; color: var(--muted); font-size: 12px; background: none; }
66
+ .reasoning { margin-bottom: 8px; border-left: 2px solid var(--border); padding-left: 10px; }
67
+ .reasoning summary { cursor: pointer; color: #8ab4ff; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .5px; }
68
+ .reasoning-body { color: var(--muted); font-size: 13px; font-style: italic; margin-top: 6px; white-space: pre-wrap; }
69
  .bot.typing span::after { content: "▊"; animation: blink 1s steps(1) infinite; color: #8ab4ff; }
70
  @keyframes blink { 50% { opacity: 0; } }
71
 
 
124
  </div>
125
  <nav>
126
  <a href="https://huggingface.co/meta-models/Muse-Glimmer-30B" target="_blank">Model Card</a>
 
 
127
  </nav>
 
128
  </header>
129
 
130
  <div class="orb">
 
216
  return t;
217
  }
218
 
219
+ // Render a bot message, splitting the model's reasoning preamble
220
+ // (everything before the "to=user" marker) into a collapsible block.
221
+ function renderBot(div, raw) {
222
+ div.innerHTML = "";
223
+ let reasoning = "", final = raw;
224
+ if (raw.includes("to=user")) {
225
+ const idx = raw.lastIndexOf("to=user");
226
+ reasoning = raw.slice(0, idx).replace(/\.?assistant\s*$/, "").trim();
227
+ final = raw.slice(idx + "to=user".length).trim();
228
+ } else {
229
+ reasoning = raw.trim();
230
+ final = "";
231
+ }
232
+ if (reasoning) {
233
+ const det = document.createElement("details");
234
+ det.className = "reasoning";
235
+ det.open = !final; // expand while still thinking, collapse once answer starts
236
+ const sum = document.createElement("summary");
237
+ sum.textContent = final ? "Reasoning" : "Thinking…";
238
+ det.appendChild(sum);
239
+ const body = document.createElement("div");
240
+ body.className = "reasoning-body";
241
+ body.textContent = reasoning;
242
+ det.appendChild(body);
243
+ div.appendChild(det);
244
+ }
245
+ const t = document.createElement("span");
246
+ t.textContent = final || "💭 thinking…";
247
+ div.appendChild(t);
248
+ }
249
+
250
  function setBusy(b) {
251
  sendBtn.style.display = b ? "none" : "";
252
  stopBtn.style.display = b ? "" : "none";
 
264
  input.style.height = "auto";
265
  setBusy(true);
266
 
267
+ const botDiv = addMsg("bot", "").parentElement;
268
+ botDiv.classList.add("typing");
269
  try {
270
  currentJob = client.submit("/chat", {
271
  message: text,
 
282
  }
283
  if (event.type === "data") {
284
  finalText = event.data[0];
285
+ renderBot(botDiv, finalText);
286
  chatEl.scrollTop = chatEl.scrollHeight;
287
  }
288
  }
289
  history.push({ role: "user", content: text || "[image]" });
290
  history.push({ role: "assistant", content: finalText });
291
  } catch (e) {
292
+ botDiv.textContent = "⚠️ " + (e.message || e);
293
  } finally {
294
+ botDiv.classList.remove("typing");
295
  setBusy(false);
296
  clearImage();
297
  queueEl.textContent = "—";