feat(ai): 业务上下文感知与 A2UI 链路统一
- 新增代码内业务上下文元数据层(实体字典 + 三大闭环工作流) - 新增 get_business_context / get_entity_schema / get_pending_tasks 运行时工具 - SYSTEM_PROMPT 与技能目录改为先查业务流程/待办再执行 - A2UI 增加 ai_a2ui_submissions 幂等表、表单过期、ui.artifact 事件 - 提交回灌携带 submissionId / fieldErrors / 下一步建议 - 前端 uiArtifacts 归一化与过期表单禁用
This commit is contained in:
@@ -3,11 +3,13 @@ import type {
|
||||
AiChatMessage,
|
||||
AiChatMessageStatus,
|
||||
AiChartSchema,
|
||||
AiArtifactSchema,
|
||||
AiFormSchema,
|
||||
AiMessageRecord,
|
||||
AiReviewSchema,
|
||||
AiToolRun,
|
||||
} from './types';
|
||||
import { mergeArtifactIntoMessage } from './provider';
|
||||
|
||||
function mapStatus(record: AiMessageRecord): AiChatMessageStatus {
|
||||
if (record.status === 'pending') return 'loading';
|
||||
@@ -50,24 +52,40 @@ function historyCharts(record: AiMessageRecord): AiChartSchema[] | 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<AiChatMessage> {
|
||||
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: {
|
||||
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',
|
||||
},
|
||||
message: baseMessage as AiChatMessage,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user