diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-activity-group.test.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-activity-group.test.tsx
new file mode 100644
index 00000000000..80fb8472a62
--- /dev/null
+++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-activity-group.test.tsx
@@ -0,0 +1,96 @@
+/**
+ * @vitest-environment jsdom
+ */
+import { act } from 'react'
+import { createRoot, type Root } from 'react-dom/client'
+import { afterEach, beforeEach, describe, expect, it } from 'vitest'
+import { ActivityStatus } from '@/components/ui/activity-status'
+import { ToolActivityGroup } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-activity-group'
+import type { ToolCallItemProps } from '@/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-call-item'
+import type { ToolCallData } from '@/app/workspace/[workspaceId]/home/types'
+
+const executingSearch: ToolCallData = {
+ id: 'search-1',
+ toolName: 'search_workspace',
+ displayTitle: 'Searching workspace',
+ status: 'executing',
+}
+
+const completedSearch: ToolCallData = {
+ ...executingSearch,
+ status: 'success',
+ result: {
+ success: true,
+ output: {
+ success: true,
+ data: {
+ results: [
+ {
+ citationId: 'document:guide',
+ citationUrl: 'https://example.test/guide',
+ documentName: 'Guide',
+ },
+ ],
+ },
+ },
+ },
+}
+
+function TestToolCall({ displayTitle, renderStatus }: ToolCallItemProps) {
+ const status = { label: displayTitle, activeLabel: displayTitle, isActive: false, icon: null }
+ return renderStatus ? renderStatus(status) :
+}
+
+describe('ToolActivityGroup search disclosure', () => {
+ let container: HTMLDivElement
+ let root: Root
+
+ beforeEach(() => {
+ container = document.createElement('div')
+ document.body.append(container)
+ root = createRoot(container)
+ })
+
+ afterEach(() => {
+ act(() => root.unmount())
+ container.remove()
+ })
+
+ function render(tool: ToolCallData, isLive: boolean) {
+ act(() =>
+ root.render(
+
+ )
+ )
+ }
+
+ function disclosure() {
+ const button = container.querySelector('[role="button"][aria-expanded]')
+ if (!button) throw new Error('Expected a search activity disclosure')
+ return button
+ }
+
+ it('opens when live results arrive, closes for the answer, and respects manual choices', () => {
+ render(executingSearch, true)
+ expect(container.querySelector('[role="button"][aria-expanded]')).toBeNull()
+
+ render(completedSearch, true)
+ expect(disclosure().getAttribute('aria-expanded')).toBe('true')
+ expect(container.querySelector('a[href="https://example.test/guide"]')).not.toBeNull()
+
+ render(completedSearch, false)
+ expect(disclosure().getAttribute('aria-expanded')).toBe('false')
+
+ act(() => disclosure().click())
+ expect(disclosure().getAttribute('aria-expanded')).toBe('true')
+ render(completedSearch, false)
+ expect(disclosure().getAttribute('aria-expanded')).toBe('true')
+ render(completedSearch, true)
+ expect(disclosure().getAttribute('aria-expanded')).toBe('true')
+
+ act(() => disclosure().click())
+ render(completedSearch, false)
+ render(completedSearch, true)
+ expect(disclosure().getAttribute('aria-expanded')).toBe('false')
+ })
+})
diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-activity-group.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-activity-group.tsx
index 1baf4c81d87..6e5b6880956 100644
--- a/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-activity-group.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/home/components/message-content/components/agent-group/tool-activity-group.tsx
@@ -220,7 +220,7 @@ export function ToolActivityGroup({
autoScrollActivity = true,
isLive = false,
}: ToolActivityGroupProps) {
- const [expanded, setExpanded] = useState(false)
+ const [manualExpanded, setManualExpanded] = useState(null)
const tools = withoutRetriedSearchFailures(calls)
const statusTool = getActivityStatusTool(tools)
if (!statusTool) return null
@@ -236,6 +236,7 @@ export function ToolActivityGroup({
const attentionKey = getActivityAttentionKey(tools)
const entries = tools.map((tool) => ({ tool, sources: getSearchActivitySources(tool) }))
const hasSearchDetails = entries.some(({ sources }) => sources !== undefined)
+ const expanded = manualExpanded ?? (isLive && hasSearchDetails)
return (
1 ? groupedActivity?.title : undefined}
collapsible={tools.length > 1 || hasSearchDetails}
expanded={expanded}
- onToggle={() => setExpanded(!expanded)}
+ onToggle={() => setManualExpanded(!expanded)}
isStreaming={working && autoScrollActivity}
unbounded={entries.some(({ sources }) => (sources?.length ?? 0) > 0)}
>