fix(computer-svc): stream для завершенных задач + Timeweb env vars

- Исправлен Stream() в computer.go: для completed/failed/cancelled задач
  сразу отправляется финальное событие и канал закрывается (ранее
  соединение зависало с socket hang up)
- Добавлены TIMEWEB_* переменные в docker-compose.yml для computer-svc
  (LLM через Timeweb Cloud AI для России)
- UI компоненты webui обновлены

Made-with: Cursor
This commit is contained in:
home
2026-02-27 05:17:42 +03:00
parent 06fe57c765
commit 120fbbaafb
19 changed files with 391 additions and 126 deletions

View File

@@ -237,6 +237,164 @@ body {
background-clip: text;
}
/* Gradient active state for selectable items */
.active-gradient {
position: relative;
background: linear-gradient(
135deg,
hsl(239 84% 74% / 0.1) 0%,
hsl(260 90% 75% / 0.08) 50%,
hsl(187 85% 65% / 0.06) 100%
);
}
.active-gradient::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
padding: 1px;
background: linear-gradient(
135deg,
hsl(239 84% 74% / 0.4) 0%,
hsl(260 90% 75% / 0.3) 50%,
hsl(187 85% 65% / 0.2) 100%
);
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
/* Gradient border for cards on hover */
.hover-gradient:hover {
position: relative;
}
.hover-gradient:hover::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
padding: 1px;
background: linear-gradient(
135deg,
hsl(239 84% 74% / 0.3) 0%,
hsl(260 90% 75% / 0.2) 50%,
hsl(187 85% 65% / 0.15) 100%
);
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
/* Gradient icon wrapper */
.icon-gradient {
display: inline-flex;
align-items: center;
justify-content: center;
background: linear-gradient(
135deg,
hsl(239 84% 74% / 0.15) 0%,
hsl(260 90% 75% / 0.1) 50%,
hsl(187 85% 65% / 0.08) 100%
);
position: relative;
}
.icon-gradient::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
padding: 1px;
background: linear-gradient(
135deg,
hsl(239 84% 74% / 0.25) 0%,
hsl(260 90% 75% / 0.2) 50%,
hsl(187 85% 65% / 0.15) 100%
);
-webkit-mask:
linear-gradient(#fff 0 0) content-box,
linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
/* Gradient focus state for inputs */
.input-gradient:focus {
outline: none;
border-color: transparent;
box-shadow: 0 0 0 1px hsl(239 84% 74% / 0.4),
0 0 0 3px hsl(239 84% 74% / 0.1);
}
/* Gradient loader */
.loader-gradient {
color: hsl(239 84% 74%);
filter: drop-shadow(0 0 8px hsl(239 84% 74% / 0.3));
}
/* Progress bar gradient */
.progress-gradient {
background: linear-gradient(
90deg,
hsl(239 84% 74%) 0%,
hsl(260 90% 75%) 50%,
hsl(187 85% 65%) 100%
);
}
/* Stat card gradient */
.stat-gradient {
background: linear-gradient(
135deg,
hsl(239 84% 74% / 0.08) 0%,
hsl(260 90% 75% / 0.05) 100%
);
border: 1px solid;
border-image: linear-gradient(
135deg,
hsl(239 84% 74% / 0.25) 0%,
hsl(187 85% 65% / 0.15) 100%
) 1;
}
/* Gradient glow effect */
.glow-gradient {
box-shadow: 0 0 20px hsl(239 84% 74% / 0.15),
0 0 40px hsl(260 90% 75% / 0.1),
0 0 60px hsl(187 85% 65% / 0.05);
}
/* Border left gradient indicator */
.border-l-gradient {
position: relative;
}
.border-l-gradient::after {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 2px;
height: 60%;
background: linear-gradient(
180deg,
hsl(239 84% 74%) 0%,
hsl(260 90% 75%) 50%,
hsl(187 85% 65%) 100%
);
border-radius: 1px;
}
/* Modern thin scrollbars */
::-webkit-scrollbar {
width: 6px;