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:
@@ -129,7 +129,7 @@ export function ChatInput({ onSend, onStop, isLoading, placeholder, autoFocus }:
|
||||
<DropdownMenu.Root>
|
||||
<DropdownMenu.Trigger asChild>
|
||||
<button className="flex items-center gap-2 h-8 px-3 text-xs text-secondary hover:text-primary rounded-lg hover:bg-surface/50 transition-all">
|
||||
<currentMode.icon className="w-4 h-4 text-accent-muted" />
|
||||
<currentMode.icon className="w-4 h-4 text-gradient" />
|
||||
<span className="font-medium">{currentMode.label}</span>
|
||||
<ChevronDown className="w-3.5 h-3.5 opacity-50" />
|
||||
</button>
|
||||
@@ -146,13 +146,13 @@ export function ChatInput({ onSend, onStop, isLoading, placeholder, autoFocus }:
|
||||
className={`
|
||||
flex items-center gap-3 px-3 py-2.5 text-sm rounded-lg cursor-pointer outline-none transition-colors
|
||||
${mode === m.value
|
||||
? 'bg-accent/10 text-primary'
|
||||
? 'active-gradient text-primary'
|
||||
: 'text-secondary hover:bg-elevated/80 hover:text-primary'
|
||||
}
|
||||
`}
|
||||
>
|
||||
<m.icon className={`w-4 h-4 ${mode === m.value ? 'text-accent' : 'text-muted'}`} />
|
||||
<span className="flex-1 font-medium">{m.label}</span>
|
||||
<m.icon className={`w-4 h-4 ${mode === m.value ? 'text-gradient' : 'text-muted'}`} />
|
||||
<span className={`flex-1 font-medium ${mode === m.value ? 'text-gradient' : ''}`}>{m.label}</span>
|
||||
<span className="text-xs text-muted">{m.desc}</span>
|
||||
</DropdownMenu.Item>
|
||||
))}
|
||||
|
||||
@@ -31,8 +31,8 @@ export function ChatMessage({ message }: ChatMessageProps) {
|
||||
>
|
||||
{isUser ? (
|
||||
<div className="max-w-[85%] flex items-start gap-3 flex-row-reverse">
|
||||
<div className="w-9 h-9 rounded-xl bg-accent/10 border border-accent/20 flex items-center justify-center flex-shrink-0">
|
||||
<User className="w-4 h-4 text-accent" />
|
||||
<div className="w-9 h-9 rounded-xl icon-gradient flex items-center justify-center flex-shrink-0">
|
||||
<User className="w-4 h-4 text-gradient" />
|
||||
</div>
|
||||
<div className="bg-surface/60 border border-border/50 rounded-2xl rounded-tr-sm px-4 py-3">
|
||||
<p className="text-[15px] text-primary leading-relaxed">{message.content}</p>
|
||||
@@ -42,8 +42,8 @@ export function ChatMessage({ message }: ChatMessageProps) {
|
||||
<div className="max-w-full">
|
||||
{/* Assistant Header */}
|
||||
<div className="flex items-center gap-2.5 mb-4">
|
||||
<div className="w-9 h-9 rounded-xl bg-accent/10 border border-accent/20 flex items-center justify-center">
|
||||
<Sparkles className="w-4 h-4 text-accent" />
|
||||
<div className="w-9 h-9 rounded-xl icon-gradient flex items-center justify-center">
|
||||
<Sparkles className="w-4 h-4 text-gradient" />
|
||||
</div>
|
||||
<span className="text-sm font-medium text-secondary">GooSeek</span>
|
||||
</div>
|
||||
@@ -78,7 +78,7 @@ export function ChatMessage({ message }: ChatMessageProps) {
|
||||
href={href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-accent hover:text-accent-hover underline underline-offset-2 decoration-accent/30 hover:decoration-accent/50 transition-colors"
|
||||
className="text-gradient hover:opacity-80 underline underline-offset-2 decoration-[hsl(239_84%_74%/0.3)] hover:decoration-[hsl(239_84%_74%/0.5)] transition-all"
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
@@ -109,7 +109,7 @@ export function ChatMessage({ message }: ChatMessageProps) {
|
||||
),
|
||||
li: ({ children }) => (
|
||||
<li className="flex gap-3 text-[15px] text-primary/85">
|
||||
<span className="text-accent/60 select-none mt-0.5">•</span>
|
||||
<span className="text-gradient opacity-60 select-none mt-0.5">•</span>
|
||||
<span className="leading-[1.6]">{children}</span>
|
||||
</li>
|
||||
),
|
||||
@@ -129,7 +129,7 @@ export function ChatMessage({ message }: ChatMessageProps) {
|
||||
</h3>
|
||||
),
|
||||
blockquote: ({ children }) => (
|
||||
<blockquote className="border-l-2 border-accent/40 pl-4 my-5 text-secondary italic">
|
||||
<blockquote className="border-l-gradient pl-4 my-5 text-secondary italic">
|
||||
{children}
|
||||
</blockquote>
|
||||
),
|
||||
@@ -143,7 +143,7 @@ export function ChatMessage({ message }: ChatMessageProps) {
|
||||
|
||||
{/* Streaming Cursor */}
|
||||
{message.isStreaming && (
|
||||
<span className="inline-block w-2 h-5 bg-accent/60 rounded-sm animate-pulse-soft ml-1" />
|
||||
<span className="inline-block w-2 h-5 progress-gradient rounded-sm animate-pulse-soft ml-1" />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -199,12 +199,12 @@ function ActionButton({ icon: Icon, label, onClick, active }: ActionButtonProps)
|
||||
className={`
|
||||
p-2 rounded-lg transition-all
|
||||
${active
|
||||
? 'text-accent bg-accent/10'
|
||||
? 'active-gradient'
|
||||
: 'text-muted hover:text-secondary hover:bg-surface/50'
|
||||
}
|
||||
`}
|
||||
>
|
||||
<Icon className="w-4 h-4" />
|
||||
<Icon className={`w-4 h-4 ${active ? 'text-gradient' : ''}`} />
|
||||
</button>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Portal>
|
||||
@@ -230,9 +230,9 @@ function CitationBadge({ citation }: { citation: CitationType }) {
|
||||
href={citation.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-2 px-3 py-2 bg-surface/40 hover:bg-surface/60 border border-border/50 hover:border-accent/30 rounded-xl transition-all group"
|
||||
className="inline-flex items-center gap-2 px-3 py-2 bg-surface/40 hover:bg-surface/60 border border-border/50 hover-gradient rounded-xl transition-all group"
|
||||
>
|
||||
<span className="w-5 h-5 rounded-md bg-accent/15 text-accent flex items-center justify-center text-xs font-semibold">
|
||||
<span className="w-5 h-5 rounded-md icon-gradient text-gradient flex items-center justify-center text-xs font-semibold">
|
||||
{citation.index}
|
||||
</span>
|
||||
{citation.favicon && (
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
FolderOpen,
|
||||
Clock,
|
||||
Settings,
|
||||
Plus,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
TrendingUp,
|
||||
@@ -68,7 +67,7 @@ export function Sidebar({ onClose }: SidebarProps) {
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.15 }}
|
||||
>
|
||||
<span className="font-bold italic text-primary tracking-tight text-lg">GooSeek</span>
|
||||
<span className="font-black italic text-primary tracking-tight text-3xl">GooSeek</span>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
@@ -94,26 +93,6 @@ export function Sidebar({ onClose }: SidebarProps) {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* New Chat Button */}
|
||||
<div className="px-3 mb-4">
|
||||
<Link
|
||||
href="/"
|
||||
onClick={handleNavClick}
|
||||
className={`
|
||||
w-full flex items-center gap-3 h-11 btn-gradient
|
||||
${isMobile || !collapsed ? 'px-3' : 'justify-center px-0'}
|
||||
`}
|
||||
>
|
||||
<Plus className="w-[18px] h-[18px] flex-shrink-0 btn-gradient-text" />
|
||||
{(isMobile || !collapsed) && (
|
||||
<span className="text-sm font-medium truncate btn-gradient-text">Новый чат</span>
|
||||
)}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Separator */}
|
||||
<div className="mx-4 border-t border-border/50" />
|
||||
|
||||
{/* Navigation */}
|
||||
<nav className="flex-1 px-3 py-4 space-y-1 overflow-y-auto">
|
||||
{navItems.map((item) => (
|
||||
@@ -184,14 +163,14 @@ function NavLink({ href, icon: Icon, label, collapsed, active, onClick }: NavLin
|
||||
flex items-center gap-3 h-11 rounded-xl transition-all duration-150
|
||||
${collapsed ? 'justify-center px-0' : 'px-3'}
|
||||
${active
|
||||
? 'bg-accent/10 text-primary border-l-2 border-accent ml-0'
|
||||
? 'active-gradient text-primary border-l-gradient ml-0'
|
||||
: 'text-secondary hover:text-primary hover:bg-surface/50'
|
||||
}
|
||||
`}
|
||||
>
|
||||
<Icon className={`w-[18px] h-[18px] flex-shrink-0 ${active ? 'text-accent' : ''}`} />
|
||||
<Icon className={`w-[18px] h-[18px] flex-shrink-0 ${active ? 'text-gradient' : ''}`} />
|
||||
{!collapsed && (
|
||||
<span className="text-sm font-medium truncate">{label}</span>
|
||||
<span className={`text-sm font-medium truncate ${active ? 'text-gradient' : ''}`}>{label}</span>
|
||||
)}
|
||||
</Link>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user