mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-23 05:02:21 +02:00
[eric] chat: keep tool body collapsed mid-stream, ease bubbles in, stop scroll-anchor fighting autoscroll
This commit is contained in:
@@ -1307,19 +1307,28 @@ const AgentChat: React.FC<AgentChatProps> = ({ sessionId: sessionIdProp, onClose
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
{/* overflow-anchor: none on the two elements that grow every frame
|
||||
(live stream + thinking dots) keeps Chromium's scroll anchoring
|
||||
from fighting our jam-to-bottom for the scroll position. The
|
||||
committed messages above keep the default anchor, so resizing a
|
||||
tool row while the user has scrolled up still holds their view. */}
|
||||
{id && (
|
||||
<StreamingBubble
|
||||
sessionId={id}
|
||||
activeBranchId={session.active_branch_id || 'main'}
|
||||
turnLabel={session.turn_label?.label}
|
||||
onStreamGrew={stickToBottomIfNeeded}
|
||||
/>
|
||||
<Box sx={{ overflowAnchor: 'none' }}>
|
||||
<StreamingBubble
|
||||
sessionId={id}
|
||||
activeBranchId={session.active_branch_id || 'main'}
|
||||
turnLabel={session.turn_label?.label}
|
||||
onStreamGrew={stickToBottomIfNeeded}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
{(awaitingResponse || (session.status === 'running' && !streamingMessageId)) && (
|
||||
<ThinkingBubble
|
||||
label={session.turn_label?.label}
|
||||
seedKey={`${session.id}:${session.messages?.length ?? 0}`}
|
||||
/>
|
||||
<Box sx={{ overflowAnchor: 'none' }}>
|
||||
<ThinkingBubble
|
||||
label={session.turn_label?.label}
|
||||
seedKey={`${session.id}:${session.messages?.length ?? 0}`}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
{showResumeBubble && session.status === 'stopped' && (
|
||||
<Box sx={{ display: 'flex', justifyContent: 'flex-start', my: 0.75 }}>
|
||||
|
||||
@@ -55,7 +55,24 @@ export const DefaultToolBubble: React.FC<DefaultToolBubbleProps> = ({
|
||||
const tc = useTermColors();
|
||||
|
||||
return (
|
||||
<Box {...selectAttrs} sx={{ maxWidth: mcpCompact ? '100%' : '85%', my: mcpCompact ? 0 : 0.5 }}>
|
||||
<Box
|
||||
{...selectAttrs}
|
||||
sx={{
|
||||
maxWidth: mcpCompact ? '100%' : '85%',
|
||||
my: mcpCompact ? 0 : 0.5,
|
||||
// Ease standalone tool calls in instead of popping. Skipped while
|
||||
// streaming (the live pill has a committed twin, so animating both
|
||||
// would flash) and when mcpCompact (rows inside a group already fade
|
||||
// via toolRowFadeIn). Transform+opacity only, so layout/scroll are untouched.
|
||||
...(!isStreaming && !mcpCompact ? {
|
||||
animation: 'toolBubbleEnter 160ms ease-out',
|
||||
'@keyframes toolBubbleEnter': {
|
||||
from: { opacity: 0, transform: 'translateY(4px)' },
|
||||
to: { opacity: 1, transform: 'translateY(0)' },
|
||||
},
|
||||
} : {}),
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
'--glow-rgb': accentRgb,
|
||||
|
||||
@@ -65,7 +65,11 @@ const ToolCallBubble: React.FC<ToolCallBubbleProps> = React.memo(
|
||||
const isInvokeAgent = isInvokeAgentTool(toolName);
|
||||
const isCreateAgent = isCreateAgentTool(toolName);
|
||||
const browserAgentAutoExpand = isBrowserAgent && isPending && !isStreaming;
|
||||
const showBody = expanded || isStreaming || browserAgentAutoExpand;
|
||||
// While the call is still streaming we keep the body CLOSED: the args land in
|
||||
// bursty clumps and force-painting them mid-stream is the jitter the user feels.
|
||||
// The header pill (tool name + glow) is the calm "what's running" signal; the
|
||||
// full args/output live behind the chevron once the call lands and is expanded.
|
||||
const showBody = expanded || browserAgentAutoExpand;
|
||||
|
||||
const resultContent = result?.content;
|
||||
const hasStructuredResult =
|
||||
|
||||
@@ -99,6 +99,14 @@ const ToolGroupBubble: React.FC<Props> = React.memo(({ group, isSessionRunning =
|
||||
my: 0.5,
|
||||
// contain: stops new tool rows from reflowing the whole transcript.
|
||||
contain: 'layout style',
|
||||
// Ease in instead of popping when a tool group appears mid-turn.
|
||||
// Transform+opacity only, so it rides the compositor and never nudges
|
||||
// layout or the scroll position. No streaming twin, so no handoff flash.
|
||||
animation: 'toolGroupEnter 160ms ease-out',
|
||||
'@keyframes toolGroupEnter': {
|
||||
from: { opacity: 0, transform: 'translateY(4px)' },
|
||||
to: { opacity: 1, transform: 'translateY(0)' },
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
|
||||
Reference in New Issue
Block a user