diff --git a/web/src/pages/TasksPage.tsx b/web/src/pages/TasksPage.tsx
index 98951f4e..b9280bbb 100644
--- a/web/src/pages/TasksPage.tsx
+++ b/web/src/pages/TasksPage.tsx
@@ -56,6 +56,7 @@ function TasksWorkspace() {
return;
}
if (event.taskId === taskId && (event.type === 'approval.pending' || event.type === 'conversation.approval_pending' || event.type === 'conversation.title_updated')) { setDetailVersion((value) => value + 1); return; }
+ if (event.taskId === taskId && event.type.startsWith('chatgpt.queue.')) return;
if (event.taskId === taskId) {
const compactEvent = compactLiveToolEvent(event);
setLiveEvents((current) => mergeTimelineEvents(current, [compactEvent]));
diff --git a/web/src/test/subagentUi.test.tsx b/web/src/test/subagentUi.test.tsx
index bb832462..676bf54b 100644
--- a/web/src/test/subagentUi.test.tsx
+++ b/web/src/test/subagentUi.test.tsx
@@ -18,7 +18,7 @@ vi.mock('../chatgpt/compact/CompactHistoryCard', () => ({ CompactHistoryCard: ()
vi.mock('../chatgpt/ChatGptConversation', () => ({ ChatGptTaskCard: () => null, ChatGptTaskComposer: () => , NewChatGptConversation: () => null }));
vi.mock('../tasks/TaskAccessCard', () => ({ TaskAccessCard: () => null }));
vi.mock('../tasks/TaskTerminalSection', () => ({ TaskTerminalSection: () => null }));
-vi.mock('../tasks/TaskTurnBubble', () => ({ TaskTurnBubble: ({ subagents }: { subagents: SubagentRun[] }) =>
{subagents.map((v) => v.name).join(', ')}
}));
+vi.mock('../tasks/TaskTurnBubble', () => ({ TaskTurnBubble: ({ turn, subagents }: { turn: { id: string }; subagents: SubagentRun[] }) => {subagents.map((v) => v.name).join(', ')}
}));
function agent(id: string, parentTaskId: string, parentTurnId = 'root-turn'): SubagentRun {
return { id, name: id, taskId: `task-${id}`, parentTaskId, parentTurnId, rootTurnId: 'root-turn', request: '', status: 'running', attempt: 1, maxRuntimeMs: 1800000, createdAtUtc: '2026-09-06T00:00:00Z', updatedAtUtc: '2026-09-06T00:00:00Z' };
@@ -50,6 +50,13 @@ describe('subagent tree and chat layout', () => {
expect(container.querySelector('.task-detail-sidebar')).toBeNull();
expect(container.querySelector('.task-detail-shell')).toHaveClass('sidebar-collapsed');
});
+ it('does not create a temporary turn bubble for ChatGPT queue events', async () => {
+ chat();
+ expect(screen.getByTestId('turn-children')).toHaveAttribute('data-turn-id', 'root-turn');
+ act(() => scene.listener?.({ id: 'queue-created', type: 'chatgpt.queue.created', taskId: 'task-chat-root', occurredAt: '2026-09-06T00:00:01Z', payload: { messageId: 'queued-1' } }));
+ await waitFor(() => expect(screen.getByTestId('turn-children')).toHaveAttribute('data-turn-id', 'root-turn'));
+ expect(screen.getAllByTestId('turn-children')).toHaveLength(1);
+ });
it('refreshes the root when a grandchild status arrives on the immediate parent task', async () => {
chat();
act(() => scene.listener?.({ id: 'grandchild-update', type: 'subagent.status', taskId: 'task-child', occurredAt: '2026-09-06T00:00:00Z', payload: { childTaskId: 'task-grandchild', status: 'completed' } }));