| ... | ... | @@ -36,10 +36,10 @@ function statusLabel(phase: string): string { |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | 38 | function workToneClass(tone: "thinking" | "tool" | "info" | "error"): string { |
| 39 | | if (tone === "thinking") return "text-sky-100"; |
| 40 | | if (tone === "tool") return "text-emerald-100"; |
| 41 | | if (tone === "error") return "text-rose-100"; |
| 42 | | return "text-[#d8d8d8]"; |
| 39 | if (tone === "error") return "text-rose-300/50"; |
| 40 | if (tone === "tool") return "text-[#8a8a8a]"; |
| 41 | if (tone === "thinking") return "text-[#707070]"; |
| 42 | return "text-[#606060]"; |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | export default function ChatView() { |
| ... | ... | @@ -341,53 +341,6 @@ export default function ChatView() { |
| 341 | 341 | </div> |
| 342 | 342 | ) : ( |
| 343 | 343 | <div className="mx-auto max-w-3xl space-y-4"> |
| 344 | | {isWorking && ( |
| 345 | | <div className="rounded-2xl border border-sky-400/20 bg-sky-500/[0.06] px-3 py-2.5"> |
| 346 | | <div className="flex items-center justify-between gap-2"> |
| 347 | | <div className="inline-flex items-center gap-2 text-xs text-sky-100"> |
| 348 | | <span className="relative inline-flex h-2.5 w-2.5"> |
| 349 | | <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-sky-300/70" /> |
| 350 | | <span className="relative inline-flex h-2.5 w-2.5 rounded-full bg-sky-200" /> |
| 351 | | </span> |
| 352 | | <span>Model is working</span> |
| 353 | | </div> |
| 354 | | <span className="text-[10px] text-sky-100/70"> |
| 355 | | {recentWorkLogEntries.length} event |
| 356 | | {recentWorkLogEntries.length === 1 ? "" : "s"} |
| 357 | | </span> |
| 358 | | </div> |
| 359 | | {recentWorkLogEntries.length === 0 ? ( |
| 360 | | <p className="pt-2 text-[11px] text-sky-100/70"> |
| 361 | | Waiting for tool/preamble updates... |
| 362 | | </p> |
| 363 | | ) : ( |
| 364 | | <div className="mt-2 max-h-48 space-y-1.5 overflow-y-auto pr-1"> |
| 365 | | {recentWorkLogEntries.map((entry) => ( |
| 366 | | <div |
| 367 | | key={entry.id} |
| 368 | | className="rounded-lg border border-white/[0.08] bg-black/20 px-2 py-1.5" |
| 369 | | > |
| 370 | | <div className="flex items-start justify-between gap-2"> |
| 371 | | <p |
| 372 | | className={`text-[11px] ${workToneClass(entry.tone)}`} |
| 373 | | > |
| 374 | | {entry.label} |
| 375 | | </p> |
| 376 | | <span className="shrink-0 text-[10px] text-[#a0a0a0]/60"> |
| 377 | | {formatTimestamp(entry.createdAt)} |
| 378 | | </span> |
| 379 | | </div> |
| 380 | | {entry.detail && ( |
| 381 | | <p className="pt-0.5 font-mono text-[11px] text-[#d0d0d0]/75"> |
| 382 | | {entry.detail} |
| 383 | | </p> |
| 384 | | )} |
| 385 | | </div> |
| 386 | | ))} |
| 387 | | </div> |
| 388 | | )} |
| 389 | | </div> |
| 390 | | )} |
| 391 | 344 | {activeThread.messages.map((msg) => ( |
| 392 | 345 | <div key={msg.id}> |
| 393 | 346 | {msg.role === "user" ? ( |
| ... | ... | @@ -433,6 +386,35 @@ export default function ChatView() { |
| 433 | 386 | )} |
| 434 | 387 | </div> |
| 435 | 388 | ))} |
| 389 | {/* Inline activity feed */} |
| 390 | {isWorking && ( |
| 391 | <div className="border-l-2 border-white/[0.05] pl-4 py-1"> |
| 392 | {recentWorkLogEntries.map((entry) => ( |
| 393 | <p |
| 394 | key={entry.id} |
| 395 | className={`py-[2px] text-[12px] leading-relaxed ${workToneClass(entry.tone)}`} |
| 396 | > |
| 397 | {entry.detail ? ( |
| 398 | <> |
| 399 | {entry.label} |
| 400 | <span className="ml-1.5 font-mono text-[11px] opacity-60"> |
| 401 | {entry.detail} |
| 402 | </span> |
| 403 | </> |
| 404 | ) : ( |
| 405 | entry.label |
| 406 | )} |
| 407 | </p> |
| 408 | ))} |
| 409 | <div className="flex items-center pt-1"> |
| 410 | <span className="inline-flex items-center gap-[3px]"> |
| 411 | <span className="h-1 w-1 rounded-full bg-white/20 animate-pulse" /> |
| 412 | <span className="h-1 w-1 rounded-full bg-white/20 animate-pulse [animation-delay:200ms]" /> |
| 413 | <span className="h-1 w-1 rounded-full bg-white/20 animate-pulse [animation-delay:400ms]" /> |
| 414 | </span> |
| 415 | </div> |
| 416 | </div> |
| 417 | )} |
| 436 | 418 | <div ref={messagesEndRef} /> |
| 437 | 419 | </div> |
| 438 | 420 | )} |