import type { MessageInfo } from '@ant-design/x-sdk'; import type { AiChatMessage, AiChatMessageStatus, AiChartSchema, AiArtifactSchema, AiFormSchema, AiMessageRecord, AiReviewSchema, AiToolRun, } from './types'; import { mergeArtifactIntoMessage } from './uiArtifacts'; function mapStatus(record: AiMessageRecord): AiChatMessageStatus { if (record.status === 'pending') return 'loading'; if (record.status === 'failed') return 'error'; if (record.status === 'cancelled') return 'abort'; return record.role === 'user' ? 'local' : 'success'; } function normalizeToolRun(tool: AiToolRun): AiToolRun { return { ...tool, status: tool.status === 'error' ? 'failed' : tool.status, summary: tool.resultSummary ?? tool.argumentsSummary ?? tool.summary, }; } function historyForms(record: AiMessageRecord): AiFormSchema[] | undefined { const a2uiForm = record.metadata?.a2uiForm; if (!a2uiForm || typeof a2uiForm !== 'object' || Array.isArray(a2uiForm)) return undefined; return [a2uiForm as AiFormSchema]; } function historyReviews(record: AiMessageRecord): AiReviewSchema[] | undefined { const a2uiReview = record.metadata?.a2uiReview; if (!a2uiReview || typeof a2uiReview !== 'object' || Array.isArray(a2uiReview)) { return undefined; } return [a2uiReview as AiReviewSchema]; } function historyCharts(record: AiMessageRecord): AiChartSchema[] | undefined { const a2uiChart = record.metadata?.a2uiChart; if (Array.isArray(a2uiChart)) { return a2uiChart.filter( (item): item is AiChartSchema => Boolean(item) && typeof item === 'object' && typeof (item as AiChartSchema).id === 'string', ); } if (!a2uiChart || typeof a2uiChart !== 'object') return undefined; return [a2uiChart as AiChartSchema]; } function historyArtifacts(record: AiMessageRecord) { const artifacts = record.metadata?.uiArtifacts; if (!Array.isArray(artifacts)) return undefined; return artifacts.filter( (item): item is AiArtifactSchema => Boolean(item) && typeof item === 'object' && typeof (item as AiArtifactSchema).id === 'string', ); } export function mapHistoryMessage(record: AiMessageRecord): MessageInfo { const artifacts = historyArtifacts(record); const baseMessage = { id: record.id, role: record.role, content: record.content || '', reasoningContent: record.reasoningContent || '', toolRuns: (record.toolRuns || []).map(normalizeToolRun), attachments: record.attachments ?? [], forms: historyForms(record), reviews: historyReviews(record), charts: historyCharts(record), replyToMessageId: record.replyToMessageId, metadata: record.metadata, error: record.status === 'failed' ? record.errorCode || 'AI 回答生成失败' : undefined, cancelled: record.status === 'cancelled', }; if (artifacts) { for (const artifact of artifacts) { mergeArtifactIntoMessage(baseMessage as AiChatMessage, artifact); } } return { id: record.id, status: mapStatus(record), message: baseMessage as AiChatMessage, }; }