feat(webui): refine output timeline and model controls (#4108)

* feat(webui): refine output timeline and composer queue

* feat(webui): add provider model picker

* fix(webui): polish model settings and heartbeat checks

* chore: keep heartbeat changes out of webui pr

* refactor(webui): isolate settings routes

* fix(providers): align minimax anthropic test

* fix(providers): keep minimax anthropic base sdk-compatible

* fix(providers): normalize anthropic base urls
This commit is contained in:
Xubin Ren
2026-05-30 23:45:26 +08:00
committed by GitHub
parent b2e43955e3
commit 3dcf511c84
65 changed files with 4526 additions and 1428 deletions
+72
View File
@@ -110,6 +110,14 @@
--tw-prose-lead: hsl(var(--foreground));
}
.markdown-content .contains-task-list {
@apply list-none pl-0;
}
.markdown-content .task-list-item {
@apply list-none pl-0;
}
/* CJK-friendly line-height: prose paragraphs default to 1.625 which is
tight for Chinese/Japanese/Korean characters. Bump to 1.8 for better
readability when the browser detects a CJK primary font. */
@@ -185,6 +193,70 @@
}
}
@keyframes composer-status-strip-enter {
0% {
max-height: 0;
opacity: 0;
transform: translateY(10px) scale(0.985);
}
72% {
max-height: var(--composer-strip-max-height, 46px);
opacity: 1;
transform: translateY(-1px) scale(1.004);
}
100% {
max-height: var(--composer-strip-max-height, 46px);
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes composer-status-strip-exit {
0% {
max-height: var(--composer-strip-max-height, 46px);
opacity: 1;
transform: translateY(0) scale(1);
}
100% {
max-height: 0;
opacity: 0;
transform: translateY(8px) scale(0.99);
}
}
.composer-status-strip {
transform-origin: bottom center;
will-change: max-height, opacity, transform;
}
.composer-status-strip[data-state="enter"] {
animation: composer-status-strip-enter 280ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
.composer-status-strip[data-state="exit"] {
animation: composer-status-strip-exit 180ms ease-in both;
}
@keyframes queued-prompt-row-enter {
0% {
opacity: 0;
transform: translateY(6px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.queued-prompt-row {
animation: queued-prompt-row-enter 220ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
@media (prefers-reduced-motion: reduce) {
.composer-status-strip {
will-change: auto;
}
.composer-status-strip[data-state] {
animation: none;
}
.queued-prompt-row {
animation: none;
}
}
/** Goal halo: pale sky blue (not ``--primary``, which often reads as neutral gray). */
@keyframes goal-shell-glow-breathe {
0%,