From 2421e336c91a01236fe12bb58d66e86f393c2bb2 Mon Sep 17 00:00:00 2001 From: Waleed Latif Date: Thu, 10 Sep 2026 15:52:26 -0700 Subject: [PATCH 1/3] improvement(chat): simplify inline tool activity --- .../hero-chat-loop/hero-chat-loop.tsx | 2 - .../hero-chat-loop/hero-tool-call-item.tsx | 8 +- .../knowledge-search-results.tsx | 7 +- .../agent-group/agent-group-view.tsx | 140 +++++++++-------- .../agent-group/agent-group.test.ts | 148 ++++++++++++++++-- .../components/agent-group/tool-call-item.tsx | 67 ++++---- .../components/agent-group/tool-call-row.tsx | 26 --- .../message-content/message-content.tsx | 11 +- apps/sim/components/ui/activity-status.tsx | 26 +++ apps/sim/components/ui/index.ts | 1 + 10 files changed, 283 insertions(+), 153 deletions(-) delete mode 100644 apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-row.tsx create mode 100644 apps/sim/components/ui/activity-status.tsx diff --git a/apps/sim/app/(landing)/components/hero/components/hero-chat-loop/hero-chat-loop.tsx b/apps/sim/app/(landing)/components/hero/components/hero-chat-loop/hero-chat-loop.tsx index a2595fd59a0..37fdc203189 100644 --- a/apps/sim/app/(landing)/components/hero/components/hero-chat-loop/hero-chat-loop.tsx +++ b/apps/sim/app/(landing)/components/hero/components/hero-chat-loop/hero-chat-loop.tsx @@ -217,7 +217,6 @@ export function HeroChatLoop({ agentLabel='Workflow Agent' items={WORKFLOW_AGENT_BUILDING_ITEMS} isStreaming - isCurrentSection isLaneOpen defaultExpanded autoScrollActivity={false} @@ -237,7 +236,6 @@ export function HeroChatLoop({ agentName='mothership' agentLabel='Sim' items={SIM_ITEMS} - defaultExpanded /> } /> ) diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/knowledge-search-results/knowledge-search-results.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/knowledge-search-results/knowledge-search-results.tsx index ecaba9120c2..1c60964abdf 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/knowledge-search-results/knowledge-search-results.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/knowledge-search-results/knowledge-search-results.tsx @@ -3,6 +3,7 @@ import { useMemo } from 'react' import { Chip, ChipLink } from '@sim/emcn' import { useQueryStates } from 'nuqs' +import { ShimmerText } from '@/components/ui/shimmer-text' import type { WorkspaceKnowledgeSearchResult, WorkspaceSearchFilters, @@ -188,7 +189,11 @@ export function KnowledgeSearchResults({ ) } if (isPending || (isFetching && !results)) { - return

Searching…

+ return ( +

+ Searching… +

+ ) } const indexingNote = diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group-view.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group-view.tsx index dd7abace0d6..e7f682d799a 100644 --- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group-view.tsx +++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/agent-group-view.tsx @@ -12,6 +12,7 @@ import { import { ChevronDown, cn, Expandable, ExpandableContent, OverflowText } from '@sim/emcn' import { ShimmerText } from '@/components/ui' import { isBrowserAgentAvailable } from '@/lib/browser-agent/transport' +import { Terminal as TerminalTool } from '@/lib/copilot/generated/tool-catalog-v1' import { RETIRED_BROWSER_REQUEST_TAKEOVER_ID } from '@/lib/copilot/tools/retired-tools' import { renderInlineMarkdown } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/inline-markdown' import type { ToolCallItemProps } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item' @@ -47,11 +48,9 @@ export interface AgentGroupProps { items: AgentGroupItem[] isDelegating?: boolean isStreaming?: boolean - /** This group is the latest section in its parent sequence (drives collapse). */ - isCurrentSection?: boolean /** The subagent lane is still open (no subagent_end yet) — i.e. actively running. */ isLaneOpen?: boolean - /** Opens the group on first render without changing production's automatic collapse rules. */ + /** Opens a subagent group on first render. */ defaultExpanded?: boolean /** Keeps the activity viewport anchored at the top while new rows stream in. */ autoScrollActivity?: boolean @@ -151,7 +150,6 @@ export function AgentGroupView({ items, isDelegating = false, isStreaming = false, - isCurrentSection = false, isLaneOpen = false, defaultExpanded = false, autoScrollActivity = true, @@ -192,16 +190,7 @@ export function AgentGroupView({ const isWorking = !activeBrowserTakeover && ((isDelegating && !resolved) || (isStreaming && isLaneOpen)) - // SUBAGENT groups never auto-expand: the collapsed row IS the live view — - // label plus latest running tool title. Expanding is a deliberate user - // action; only a pending permission prompt or a browser hand-back forces - // one open. The MAIN lane ("Sim") is not a delegation card: its narration - // and tool calls are the turn itself, so it keeps the original live-expand - // behavior (open while streaming/current, settles when superseded). - const autoExpanded = isMainAgent && isStreaming && (isCurrentSection || isLaneOpen || !resolved) - const [manualExpanded, setManualExpanded] = useState( - defaultExpanded ? true : null - ) + const [manualExpanded, setManualExpanded] = useState(defaultExpanded) const [expandedTakeoverId, setExpandedTakeoverId] = useState(null) // An outstanding permission prompt overrides a manual collapse: the turn // cannot proceed until it is answered, so hiding it would deadlock the chat @@ -209,9 +198,7 @@ export function AgentGroupView({ const expanded = hasAwaitingApproval(items) || nestedBrowserTakeover || - (activeBrowserTakeover - ? expandedTakeoverId === activeBrowserTakeover.id - : (manualExpanded ?? autoExpanded)) + (activeBrowserTakeover ? expandedTakeoverId === activeBrowserTakeover.id : manualExpanded) const toggleExpanded = () => { if (activeBrowserTakeover) { @@ -221,9 +208,74 @@ export function AgentGroupView({ setManualExpanded(!expanded) } + let latestTool: AgentGroupItem | undefined + if (isMainAgent) { + for (let index = items.length - 1; index >= 0; index--) { + if (items[index].type === 'tool') { + latestTool = items[index] + break + } + } + } + /** Keep blocking controls visible even when a newer tool replaces the activity text. */ + const visibleItems = isMainAgent + ? items.filter( + (item) => + item.type !== 'tool' || + item === latestTool || + item.data.status === ToolCallStatus.awaiting_approval || + (item.data.status === ToolCallStatus.executing && + item.data.toolName === TerminalTool.id && + item.data.params?.operation === 'handoff') + ) + : items + const activity = ( +
+ {visibleItems.map((item, idx) => { + if (item.type === 'tool') { + return ( + + ) + } + if (item.type === 'agent_group') { + return ( + + ) + } + return ( + + ) + })} +
+ ) + return (
- {hasItems ? ( + {isMainAgent ? null : hasItems ? (