diff --git a/apps/desktop/src/hooks/use-local-chat.ts b/apps/desktop/src/hooks/use-local-chat.ts index caacf681..ebe19d0c 100644 --- a/apps/desktop/src/hooks/use-local-chat.ts +++ b/apps/desktop/src/hooks/use-local-chat.ts @@ -6,6 +6,7 @@ */ import { useState, useEffect, useCallback, useRef } from 'react' import { useMessagesStore } from '@multica/store' +import type { ContentBlock } from '@multica/sdk' interface UseLocalChatOptions { agentId: string @@ -45,7 +46,15 @@ export function useLocalChat({ agentId }: UseLocalChatOptions): UseLocalChatRetu try { const result = await window.electronAPI.localChat.getHistory(agentId) if (result.messages && result.messages.length > 0) { - useMessagesStore.getState().loadMessages(result.messages) + // Normalize: IPC may return content as string, store expects ContentBlock[] + useMessagesStore.getState().loadMessages( + result.messages.map((m: Record) => ({ + ...m, + content: typeof m.content === 'string' + ? (m.content ? [{ type: 'text' as const, text: m.content }] : []) + : (m.content ?? []), + })) as import('@multica/store').Message[] + ) } } catch { // History load is best-effort @@ -74,18 +83,17 @@ export function useLocalChat({ agentId }: UseLocalChatOptions): UseLocalChatRetu if (agentEvent.type === 'message_start') { currentStreamRef.current = streamId store.startStream(streamId, agentId) - // Extract initial text if any - const text = extractTextFromAgentEvent(agentEvent) - if (text) store.appendStream(streamId, text) + const content = extractContentFromAgentEvent(agentEvent) + if (content.length) store.appendStream(streamId, content) } else if (agentEvent.type === 'message_update') { - const text = extractTextFromAgentEvent(agentEvent) - if (text && currentStreamRef.current) { - store.appendStream(currentStreamRef.current, text) + const content = extractContentFromAgentEvent(agentEvent) + if (content.length && currentStreamRef.current) { + store.appendStream(currentStreamRef.current, content) } } else if (agentEvent.type === 'message_end') { - const text = extractTextFromAgentEvent(agentEvent) + const content = extractContentFromAgentEvent(agentEvent) if (currentStreamRef.current) { - store.endStream(currentStreamRef.current, text) + store.endStream(currentStreamRef.current, content) currentStreamRef.current = null } setIsLoading(false) @@ -131,14 +139,9 @@ export function useLocalChat({ agentId }: UseLocalChatOptions): UseLocalChatRetu } } -/** - * Extract text content from AgentEvent message. - * Same logic as @multica/sdk extractTextFromEvent. - */ -function extractTextFromAgentEvent(event: { message?: { content?: Array<{ type: string; text?: string }> } }): string { - if (!event.message?.content) return '' - return event.message.content - .filter((c): c is { type: 'text'; text: string } => c.type === 'text' && !!c.text) - .map((c) => c.text) - .join('') +/** Extract content blocks from AgentEvent message */ +function extractContentFromAgentEvent(event: { message?: { content?: unknown } }): ContentBlock[] { + if (!event.message?.content) return [] + const content = event.message.content + return Array.isArray(content) ? content as ContentBlock[] : [] }