Fix user→tool call spacing in timeline
This commit is contained in:
@@ -212,37 +212,46 @@ export function AgentStreamView({
|
|||||||
const tightGap = theme.spacing[1]; // 4px
|
const tightGap = theme.spacing[1]; // 4px
|
||||||
const looseGap = theme.spacing[4]; // 16px
|
const looseGap = theme.spacing[4]; // 16px
|
||||||
|
|
||||||
// In inverted lists, marginBottom renders as visual gap ABOVE the item.
|
// The FlatList is inverted, but each row is re-inverted by RN, so `marginBottom` still
|
||||||
// Index 0 is visually at the bottom, so use the item ABOVE (index + 1) to compute spacing.
|
// manifests as the gap *below* the row in the final visual layout. Compute spacing
|
||||||
const getGapAbove = useCallback(
|
// against the item visually below (index - 1 in our inverted list).
|
||||||
|
const getGapBelow = useCallback(
|
||||||
(item: StreamItem, index: number) => {
|
(item: StreamItem, index: number) => {
|
||||||
const aboveItem = flatListData[index + 1];
|
const belowItem = flatListData[index - 1];
|
||||||
if (!aboveItem) {
|
if (!belowItem) {
|
||||||
// This is the topmost item; nothing above it visually.
|
// This is the bottommost (newest) item; nothing below it visually.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same type groups get tight gap (4px)
|
// Same type groups get tight gap (4px)
|
||||||
if (isUserMessageItem(item) && isUserMessageItem(aboveItem)) {
|
if (isUserMessageItem(item) && isUserMessageItem(belowItem)) {
|
||||||
return tightGap;
|
return tightGap;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isToolSequenceItem(item) && isToolSequenceItem(aboveItem)) {
|
if (isToolSequenceItem(item) && isToolSequenceItem(belowItem)) {
|
||||||
return tightGap;
|
return tightGap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep tool sequences visually connected to the preceding user message / tasks.
|
// Give user messages more breathing room before tool sequences.
|
||||||
|
if (item.kind === "user_message" && isToolSequenceItem(belowItem)) {
|
||||||
|
return looseGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep tool sequences visually connected to the preceding user/assistant message.
|
||||||
if (
|
if (
|
||||||
isToolSequenceItem(item) &&
|
(item.kind === "user_message" || item.kind === "assistant_message") &&
|
||||||
(aboveItem.kind === "user_message" ||
|
isToolSequenceItem(belowItem)
|
||||||
aboveItem.kind === "assistant_message" ||
|
|
||||||
aboveItem.kind === "todo_list")
|
|
||||||
) {
|
) {
|
||||||
return tightGap;
|
return tightGap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// And keep assistant messages visually connected to tool sequences (symmetry).
|
// Keep todo lists visually connected to the following tool sequence (symmetry).
|
||||||
if (item.kind === "assistant_message" && isToolSequenceItem(aboveItem)) {
|
if (item.kind === "todo_list" && isToolSequenceItem(belowItem)) {
|
||||||
|
return tightGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep tool sequences visually connected to the assistant response (symmetry).
|
||||||
|
if (isToolSequenceItem(item) && belowItem.kind === "assistant_message") {
|
||||||
return tightGap;
|
return tightGap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,7 +389,7 @@ export function AgentStreamView({
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gapAbove = getGapAbove(item, index);
|
const gapBelow = getGapBelow(item, index);
|
||||||
|
|
||||||
// Check if this is the end of a turn (before a user message or end of stream when not running)
|
// Check if this is the end of a turn (before a user message or end of stream when not running)
|
||||||
// In inverted list: index-1 is the next item (newer in time)
|
// In inverted list: index-1 is the next item (newer in time)
|
||||||
@@ -393,14 +402,14 @@ export function AgentStreamView({
|
|||||||
const getContent = () => collectTurnContent(index);
|
const getContent = () => collectTurnContent(index);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[stylesheet.streamItemWrapper, { marginBottom: gapAbove }]}>
|
<View style={[stylesheet.streamItemWrapper, { marginBottom: gapBelow }]}>
|
||||||
{content}
|
{content}
|
||||||
{isEndOfTurn ? <TurnCopyButton getContent={getContent} /> : null}
|
{isEndOfTurn ? <TurnCopyButton getContent={getContent} /> : null}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
getGapAbove,
|
getGapBelow,
|
||||||
renderStreamItemContent,
|
renderStreamItemContent,
|
||||||
flatListData,
|
flatListData,
|
||||||
agent.status,
|
agent.status,
|
||||||
|
|||||||
Reference in New Issue
Block a user