feat(ui): 实现消息 parts 有序渲染

- Server: API 返回 parts 数组保持原始顺序
- Server: 添加 MessagePart 类型定义 (text/tool/reasoning)
- UI: ChatMessage 按 parts 顺序交叉渲染文本和工具调用
- UI: 新增 ToolPartItem 组件渲染单个工具 part
- UI: useChat 创建消息时添加 parts 字段
This commit is contained in:
2025-12-15 14:46:00 +08:00
parent 2150abde7c
commit cd0dd814ab
5 changed files with 280 additions and 32 deletions
+6 -2
View File
@@ -123,11 +123,13 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
case 'done':
setState((prev) => {
const content = message.payload?.content || prev.streamingContent;
const newMessage: Message = {
id: message.payload?.id || `assistant-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
role: 'assistant',
content: message.payload?.content || prev.streamingContent,
timestamp: message.payload?.timestamp || new Date().toISOString(),
parts: [{ type: 'text', id: `text-${Date.now()}`, text: content }],
content,
};
return {
...prev,
@@ -141,11 +143,13 @@ export function useChat({ sessionId, onError, onSessionNotFound, onSessionUpdate
case 'message_received':
// 用户消息已确认 - 构建完整的消息对象
setState((prev) => {
const content = message.payload?.content || '';
const userMessage: Message = {
id: `user-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
role: 'user',
content: message.payload?.content || '',
timestamp: new Date().toISOString(),
parts: [{ type: 'text', id: `text-${Date.now()}`, text: content }],
content,
};
return {
...prev,