feat: add enhanced MULTIX UI features

Added all missing MULTIX enhancements matching the original screenshot:

1. STREAMING indicator:
   - Animated purple badge with sparkles icon
   - Shows live token count during streaming
   - Pulsing animation effect

2. Status badges:
   - PENDING/RUNNING/DONE badges for tasks
   - Color-coded based on status

3. APEX/SHIELD renamed:
   - 'Auto' -> 'APEX' with tooltip
   - 'Shield' -> 'SHIELD' with tooltip

4. THINKING indicator:
   - Bouncing dots animation (3 dots)
   - Shows THINKING or SENDING status

5. STOP button:
   - Red stop button appears during agent work
   - Calls cancel endpoint to interrupt

6. Detailed token stats bar:
   - INPUT/OUTPUT tokens
   - REASONING tokens (amber)
   - CACHE READ (emerald)
   - CACHE WRITE (cyan)
   - COST (violet)
   - MODEL (indigo)

7. Message navigation sidebar:
   - YOU/ASST labels for each message
   - Click to scroll to message
   - Appears on right side when viewing task
This commit is contained in:
Gemini AI
2025-12-23 13:49:17 +04:00
Unverified
parent 00bee04867
commit 55f5945b61
6 changed files with 915 additions and 28 deletions

View File

@@ -633,36 +633,35 @@ export default function MultiTaskChat(props: MultiTaskChatProps) {
</div>
</div>
</div>
</div>
{/* Message Navigation Sidebar - YOU/ASST labels */}
<Show when={selectedTaskId() && filteredMessageIds().length > 0}>
<div class="w-12 shrink-0 bg-zinc-900/40 border-l border-white/5 overflow-y-auto py-2 px-1 flex flex-col items-center gap-1">
<For each={filteredMessageIds()}>
{(messageId, index) => {
const msg = () => messageStore().getMessage(messageId);
const isUser = () => msg()?.role === "user";
return (
<button
onClick={() => {
// Scroll to message
const element = document.getElementById(`msg-${messageId}`);
element?.scrollIntoView({ behavior: "smooth", block: "center" });
}}
class={`w-9 py-1 rounded text-[8px] font-black uppercase transition-all ${isUser()
{/* Message Navigation Sidebar - YOU/ASST labels */}
<Show when={selectedTaskId() && filteredMessageIds().length > 0}>
<div class="w-12 shrink-0 bg-zinc-900/40 border-l border-white/5 overflow-y-auto py-2 px-1 flex flex-col items-center gap-1">
<For each={filteredMessageIds()}>
{(messageId, index) => {
const msg = () => messageStore().getMessage(messageId);
const isUser = () => msg()?.role === "user";
return (
<button
onClick={() => {
// Scroll to message
const element = document.getElementById(`msg-${messageId}`);
element?.scrollIntoView({ behavior: "smooth", block: "center" });
}}
class={`w-9 py-1 rounded text-[8px] font-black uppercase transition-all ${isUser()
? "bg-indigo-500/20 border border-indigo-500/40 text-indigo-400 hover:bg-indigo-500/30"
: "bg-emerald-500/20 border border-emerald-500/40 text-emerald-400 hover:bg-emerald-500/30"
}`}
title={`${isUser() ? "User" : "Assistant"} message ${index() + 1}`}
>
{isUser() ? "YOU" : "ASST"}
</button>
);
}}
</For>
</div>
</Show>
</div>
</main >
}`}
title={`${isUser() ? "User" : "Assistant"} message ${index() + 1}`}
>
{isUser() ? "YOU" : "ASST"}
</button>
);
}}
</For>
</div>
</Show>
</div>
</main>
);
}