INVESTIGATION_THINKING_BLOCKS.md
In team mode, thinking blocks show two instances:
In single-chat mode, only one thinking block appears and is properly collapsed by default.
Flow:
useAcpMessage hook (line 29 in useAcpMessage.ts)thinking eventshandleResponseMessage at line 115-306 in useAcpMessage.ts processes the messagetransformMessage (chatLib.ts:545-564)addOrUpdateMessage accumulates thinking content via message index (hooks.ts:196-229)status fieldexpanded = !isDone (line 44 in MessageThinking.tsx)
Flow:
team_id prop (line 90 in AcpSendBox.tsx)team.sendMessage IPC (line 202 in AcpSendBox.tsx)THE PROBLEM - Dual Thinking Message Emission:
Looking at AcpAgentManager.ts:1138-1147, emitThinkingMessage emits:
ipcBridge.acpConversation.responseStream.emit({
type: 'thinking',
conversation_id: this.conversation_id,
msg_id: this.thinkingMsgId,
data: { content, duration, status },
});
Critical Issue at line 710-717 in AcpAgentManager.ts:
ipcBridge.acpConversation.responseStream.emit(processedMessage); // Line 710
// Only emit terminal events to team bus for agent lifecycle management
if (processedMessage.type === 'finish' || processedMessage.type === 'error') {
teamEventBus.emit('responseStream', { ... }); // Line 713
}
The bug: Thinking messages are only emitted to ipcBridge.acpConversation.responseStream, NOT to teamEventBus. This means in team mode:
Stream thinking event (immediate) → emitted via ipcBridge only
Persisted thinking message (DB flush) → persisted to database via flushThinkingToDb (line 1159)
status='done' (collapsed)Result in team mode: Both messages appear in the list because:
composeMessageWithIndex (hooks.ts:196-229) only merges messages with same msg_idmsg_id, but they come from different sources (stream vs DB)In single-chat mode:
useMessageLstCache logic (lines 385-409) compares stream vs DB content:
BUT in team mode, the thinking message stream event is NOT being routed to team participants, so they only see the DB version (collapsed, complete) while the leader sees both.
File: src/renderer/pages/conversation/Messages/components/MessageThinking.tsx:42-54
const { content: text, status, duration, subject } = message.content;
const isDone = status === 'done';
const [expanded, setExpanded] = useState(!isDone); // Line 44
// Auto-collapse when status changes to done
useEffect(() => {
if (isDone) {
setExpanded(false);
}
}, [isDone]);
Issue: There are TWO thinking messages:
status='thinking' (expanded by default)status='done' (collapsed by default)| File | Lines | Issue |
|---|---|---|
src/process/task/AcpAgentManager.ts | 1138-1147 | emitThinkingMessage only emits to ipcBridge.acpConversation.responseStream |
src/process/task/AcpAgentManager.ts | 710-717 | Only finish and error events emitted to teamEventBus; thinking should be included |
src/process/task/AcpAgentManager.ts | 1159-1179 | flushThinkingToDb persists thinking with status; creates duplicate in team mode |
src/renderer/pages/conversation/Messages/hooks.ts | 196-229 | Message deduplication works correctly but receives duplicate messages |
src/renderer/pages/conversation/Messages/components/MessageThinking.tsx | 42-54 | Default expansion state logic is correct but applied to duplicate messages |
Stream Event (running): status='thinking', emitted to ipcBridge
Persisted Message (done): status='done', saved to DB and loaded on team member view
useMessageLstCache → ipcBridge.database.getConversationMessagesMessage list sees BOTH:
msg_id for merging| Aspect | Single-Chat | Team Mode |
|---|---|---|
| Stream thinking events | Emitted via ipcBridge | Emitted via ipcBridge only |
| Team event bus relay | N/A | NOT relayed for thinking (only finish/error) |
| DB persistence | Normal | Same as single-chat |
| Message deduplication | Works (stream + DB merged intelligently) | Fails (duplicate thinking messages) |
| Expansion state | Correct (one message) | Wrong (duplicate messages with different states) |
Option A (Minimal): Relay thinking messages to team event bus
src/process/task/AcpAgentManager.tsOption B (Comprehensive): Improve team-mode-specific handling
Option C (Correct): Fix root cause in message emission