fix(desktop): update use-local-chat to use ContentBlock[] instead of string

Message.content changed from string to ContentBlock[] — update desktop's
local chat hook to match: extractContentFromAgentEvent returns ContentBlock[],
and history messages are normalized from string to ContentBlock[].

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Naiyuan Qing 2026-02-04 18:50:44 +08:00
parent 83e1210ec0
commit c412e44f10

View file

@ -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<string, unknown>) => ({
...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[] : []
}