mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-13 05:07:40 +02:00
[eric] perf+ui: shrink runs chunks in parallel (5min -> ~1min) and shows a live pulsing label so users know its working
This commit is contained in:
@@ -528,10 +528,15 @@ async def summarize_file(req: _SummarizeRequest):
|
||||
else:
|
||||
chunks = [raw[i:i + CHUNK_CHARS] for i in range(0, len(raw), CHUNK_CHARS)]
|
||||
per_chunk_budget = max(800, req.target_tokens // len(chunks) + 600)
|
||||
partials = []
|
||||
for i, ch in enumerate(chunks):
|
||||
label = f"{os.path.basename(src)} (part {i + 1} of {len(chunks)})"
|
||||
partials.append(await _summarize_block(ch, per_chunk_budget, label))
|
||||
# Parallel summarization. Sequential was N chunks * ~60s each
|
||||
# (5+ min wall time for a 4-chunk PDF on Haiku). Aux providers
|
||||
# all handle parallel requests fine; the only ceiling is the
|
||||
# provider's per-key rate limit, and a single user summarizing
|
||||
# one file will never hit that.
|
||||
partials = await asyncio.gather(*[
|
||||
_summarize_block(ch, per_chunk_budget, f"{os.path.basename(src)} (part {i + 1} of {len(chunks)})")
|
||||
for i, ch in enumerate(chunks)
|
||||
])
|
||||
merge_input = "\n\n".join(f"## Part {i + 1}\n{p}" for i, p in enumerate(partials))
|
||||
summary = await _summarize_block(merge_input, req.target_tokens, f"merged summary of {os.path.basename(src)}")
|
||||
except Exception as e:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import Modal from '@mui/material/Modal';
|
||||
@@ -6,6 +6,37 @@ import Snackbar from '@mui/material/Snackbar';
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import { ClaudeTokens } from '@/shared/styles/claudeTokens';
|
||||
|
||||
const SHRINK_PROGRESS_MESSAGES = [
|
||||
'Reading the file',
|
||||
'Pulling out the key bits',
|
||||
'Compressing',
|
||||
'Almost done',
|
||||
];
|
||||
|
||||
function ShrinkingLabel() {
|
||||
const [idx, setIdx] = useState(0);
|
||||
useEffect(() => {
|
||||
const t = setInterval(() => setIdx((i) => (i + 1) % SHRINK_PROGRESS_MESSAGES.length), 4000);
|
||||
return () => clearInterval(t);
|
||||
}, []);
|
||||
return (
|
||||
<Box component="span" sx={{ display: 'inline-flex', alignItems: 'center', gap: 0.5 }}>
|
||||
<Box component="span" sx={{
|
||||
display: 'inline-block', width: 8, height: 8, borderRadius: '50%',
|
||||
bgcolor: 'currentColor', opacity: 0.85,
|
||||
animation: 'osw-pulse 1.2s ease-in-out infinite',
|
||||
'@keyframes osw-pulse': {
|
||||
'0%, 100%': { transform: 'scale(0.6)', opacity: 0.45 },
|
||||
'50%': { transform: 'scale(1)', opacity: 0.95 },
|
||||
},
|
||||
}} />
|
||||
<Box component="span" sx={{ minWidth: 130, textAlign: 'left' }}>
|
||||
{SHRINK_PROGRESS_MESSAGES[idx]}…
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
interface Props {
|
||||
c: ClaudeTokens;
|
||||
lightboxSrc: string | null;
|
||||
@@ -100,11 +131,12 @@ export const ChatInputOverlays: React.FC<Props> = ({
|
||||
border: 'none', borderRadius: '6px',
|
||||
px: 1.5, py: 0.7, fontSize: '0.82rem', fontWeight: 500, cursor: 'pointer',
|
||||
whiteSpace: 'nowrap',
|
||||
transition: 'background 0.15s ease, opacity 0.15s ease',
|
||||
'&:hover': { bgcolor: c.accent.hover },
|
||||
'&:disabled': { opacity: 0.6, cursor: 'wait' },
|
||||
'&:disabled': { opacity: 0.85, cursor: 'wait', bgcolor: c.accent.primary },
|
||||
}}
|
||||
>
|
||||
{summarizingPath === oversizeQueue[0]?.path ? 'Shrinking…' : 'Shrink it'}
|
||||
{summarizingPath === oversizeQueue[0]?.path ? <ShrinkingLabel /> : 'Shrink it'}
|
||||
</Box>
|
||||
<Box
|
||||
component="button"
|
||||
|
||||
Reference in New Issue
Block a user