mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-23 10:08:38 +02:00
fix: resolve chat message duplication and empty thinking blocks
- Refactor useApp.ts to pass through original data without accumulation - ChatView is now the single source of truth for chunk accumulation - Add empty content check in ThoughtBlockView to skip rendering whitespace-only thoughts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -377,6 +377,9 @@ function TextContentBlock({ content }: { content: string }) {
|
||||
|
||||
// Thought block view - expanded, collapsible
|
||||
function ThoughtBlockView({ text }: { text: string }) {
|
||||
// Skip rendering if content is empty or only whitespace
|
||||
if (!text || !text.trim()) return null
|
||||
|
||||
const [isExpanded, setIsExpanded] = useState(false)
|
||||
const isLong = text.length > 200
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Main application state hook
|
||||
*/
|
||||
import { useState, useEffect, useCallback, useRef } from 'react'
|
||||
import { useState, useEffect, useCallback } from 'react'
|
||||
import type {
|
||||
MulticaSession,
|
||||
StoredSessionUpdate,
|
||||
@@ -56,9 +56,6 @@ export function useApp(): AppState & AppActions {
|
||||
? runningSessionsStatus.processingSessionIds.includes(currentSession.id)
|
||||
: false
|
||||
|
||||
// Track streaming text for current message
|
||||
const streamingTextRef = useRef<string>('')
|
||||
|
||||
// Load sessions on mount
|
||||
useEffect(() => {
|
||||
loadSessions()
|
||||
@@ -71,71 +68,24 @@ export function useApp(): AppState & AppActions {
|
||||
// Subscribe to agent events
|
||||
useEffect(() => {
|
||||
const unsubMessage = window.electronAPI.onAgentMessage((message) => {
|
||||
// Log all incoming ACP messages for debugging
|
||||
console.log('[ACP Message]', JSON.stringify(message, null, 2))
|
||||
|
||||
// Only process messages for the current session
|
||||
// message.sessionId is ACP Agent Session ID, compare with currentAgentSessionId
|
||||
if (!currentAgentSessionId || message.sessionId !== currentAgentSessionId) {
|
||||
console.log('[ACP] Ignoring message for different session:', message.sessionId, 'current:', currentAgentSessionId)
|
||||
return
|
||||
}
|
||||
|
||||
const update = message.update
|
||||
const updateType = update?.sessionUpdate
|
||||
console.log('[ACP Update Type]', updateType)
|
||||
|
||||
// Handle streaming text accumulation for agent messages
|
||||
if (updateType === 'agent_message_chunk' && update.content?.type === 'text') {
|
||||
streamingTextRef.current += update.content.text
|
||||
}
|
||||
|
||||
// Add the update to session updates for real-time display
|
||||
// Pass through original update without any accumulation
|
||||
// ChatView is responsible for accumulating chunks into complete messages
|
||||
setSessionUpdates((prev) => {
|
||||
const now = new Date().toISOString()
|
||||
|
||||
// For agent_message_chunk, we want to show accumulated text
|
||||
if (updateType === 'agent_message_chunk') {
|
||||
const streamingUpdate: StoredSessionUpdate = {
|
||||
timestamp: now,
|
||||
update: {
|
||||
sessionId: message.sessionId,
|
||||
update: {
|
||||
sessionUpdate: 'agent_message_chunk',
|
||||
content: { type: 'text', text: streamingTextRef.current },
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Replace last streaming update if it was also agent_message_chunk
|
||||
const lastIdx = prev.length - 1
|
||||
if (lastIdx >= 0) {
|
||||
const last = prev[lastIdx]
|
||||
if (
|
||||
last.update.update &&
|
||||
'sessionUpdate' in last.update.update &&
|
||||
last.update.update.sessionUpdate === 'agent_message_chunk'
|
||||
) {
|
||||
return [...prev.slice(0, lastIdx), streamingUpdate]
|
||||
}
|
||||
}
|
||||
return [...prev, streamingUpdate]
|
||||
}
|
||||
|
||||
// For all other update types, add them directly
|
||||
const newUpdate = {
|
||||
timestamp: now,
|
||||
timestamp: new Date().toISOString(),
|
||||
update: {
|
||||
sessionId: message.sessionId,
|
||||
update: update,
|
||||
update: message.update,
|
||||
},
|
||||
} as StoredSessionUpdate
|
||||
return [...prev, newUpdate]
|
||||
})
|
||||
|
||||
if (message.done) {
|
||||
streamingTextRef.current = ''
|
||||
}
|
||||
})
|
||||
|
||||
const unsubStatus = window.electronAPI.onAgentStatus((status) => {
|
||||
@@ -238,7 +188,6 @@ export function useApp(): AppState & AppActions {
|
||||
|
||||
try {
|
||||
setError(null)
|
||||
streamingTextRef.current = ''
|
||||
|
||||
// Add user message to updates (use a custom marker for UI display)
|
||||
// 'user_message' is a custom type not in ACP SDK, used for UI purposes only
|
||||
|
||||
Reference in New Issue
Block a user