Align active agent pill with timeline text

Render active agent process pills inline with the message timeline so they sit under the latest message text instead of the composer edge.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Thomas Petersen
2026-05-04 19:02:52 -04:00
parent cfaf3b5369
commit e40d4e71e3
3 changed files with 45 additions and 32 deletions

View File

@@ -56,7 +56,7 @@ export function BotActivityBar({
return (
<div
className="flex min-w-0 shrink items-center justify-end gap-1 overflow-hidden"
className="flex min-w-0 shrink items-center justify-start gap-1 overflow-hidden"
data-testid="bot-activity-bar"
>
{visibleAgents.map((agent) => {

View File

@@ -229,6 +229,8 @@ export const ChannelPane = React.memo(function ChannelPane({
activeChannel.archivedAt !== null ||
activeChannel.channelType === "forum" ||
isSending;
const hasTypingActivity = typingPubkeys.length > 0;
const hasBotActivity = botTypingPubkeys.length > 0;
const selectedAgent = React.useMemo(
() =>
@@ -260,6 +262,18 @@ export const ChannelPane = React.memo(function ChannelPane({
currentPubkey={currentPubkey}
fetchOlder={fetchOlder}
hasOlderMessages={hasOlderMessages}
inlineFooter={
hasBotActivity ? (
<div className="flex justify-start pl-[3.125rem]">
<BotActivityBar
agents={agentSessionAgents}
onOpenAgentSession={onOpenAgentSession}
openAgentSessionPubkey={openAgentSessionPubkey}
typingBotPubkeys={botTypingPubkeys}
/>
</div>
) : null
}
isFetchingOlder={isFetchingOlder}
personaLookup={personaLookup}
profiles={profiles}
@@ -287,6 +301,16 @@ export const ChannelPane = React.memo(function ChannelPane({
searchQuery={channelFind.query}
targetMessageId={targetMessageId}
/>
{hasTypingActivity ? (
<div className="relative bg-background">
<TypingIndicatorRow
channel={activeChannel}
currentPubkey={currentPubkey}
profiles={profiles}
typingPubkeys={typingPubkeys}
/>
</div>
) : null}
{isNonMemberView ? (
<div
data-testid="join-banner"
@@ -338,22 +362,6 @@ export const ChannelPane = React.memo(function ChannelPane({
/>
</div>
)}
<div className="relative bg-background">
<TypingIndicatorRow
channel={activeChannel}
currentPubkey={currentPubkey}
profiles={profiles}
typingPubkeys={typingPubkeys}
/>
<div className="absolute right-0 top-0 flex h-8 items-center pr-8 sm:pr-10">
<BotActivityBar
agents={agentSessionAgents}
onOpenAgentSession={onOpenAgentSession}
openAgentSessionPubkey={openAgentSessionPubkey}
typingBotPubkeys={botTypingPubkeys}
/>
</div>
</div>
</div>
{threadHeadMessage ? (

View File

@@ -15,6 +15,7 @@ import { useTimelineScrollManager } from "./useTimelineScrollManager";
type MessageTimelineProps = {
channelId?: string | null;
messages: TimelineMessage[];
inlineFooter?: React.ReactNode;
isLoading?: boolean;
emptyTitle?: string;
emptyDescription?: string;
@@ -47,6 +48,7 @@ type MessageTimelineProps = {
export const MessageTimeline = React.memo(function MessageTimeline({
channelId,
messages,
inlineFooter,
isLoading = false,
emptyTitle = "No messages yet",
emptyDescription = "Send the first message to start the thread.",
@@ -172,21 +174,24 @@ export const MessageTimeline = React.memo(function MessageTimeline({
) : null}
{!isLoading && messages.length > 0 ? (
<TimelineMessageList
activeReplyTargetId={activeReplyTargetId}
currentPubkey={currentPubkey}
highlightedMessageId={highlightedMessageId}
messages={messages}
onDelete={onDelete}
onEdit={onEdit}
onReply={onReply}
onToggleReaction={onToggleReaction}
personaLookup={personaLookup}
profiles={profiles}
searchActiveMessageId={searchActiveMessageId}
searchMatchingMessageIds={searchMatchingMessageIds}
searchQuery={searchQuery}
/>
<>
<TimelineMessageList
activeReplyTargetId={activeReplyTargetId}
currentPubkey={currentPubkey}
highlightedMessageId={highlightedMessageId}
messages={messages}
onDelete={onDelete}
onEdit={onEdit}
onReply={onReply}
onToggleReaction={onToggleReaction}
personaLookup={personaLookup}
profiles={profiles}
searchActiveMessageId={searchActiveMessageId}
searchMatchingMessageIds={searchMatchingMessageIds}
searchQuery={searchQuery}
/>
{inlineFooter}
</>
) : null}
<div aria-hidden className="h-px" ref={bottomAnchorRef} />