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:
2026-08-06 15:23:23 +08:00
parent d9c541dacc
commit 24e0ecbdaf
44 changed files with 2125 additions and 41 deletions

View File

@@ -154,6 +154,41 @@ describe('AI chat SSE message reducer', () => {
expect(message.forms?.[1]).toMatchObject({ id: 'form-2' });
});
it('merges ui.artifact events into uiArtifacts and legacy lists by id', () => {
let message = reduceAiSseMessage(undefined, {
event: 'ui.artifact',
data: JSON.stringify({
messageId: 12,
artifact: {
id: 'form-1',
type: 'form',
status: 'pending',
messageId: 12,
conversationId: 3,
payload: { id: 'form-1', title: '新增学生', fields: [] },
},
}),
});
message = reduceAiSseMessage(message, {
event: 'ui.artifact',
data: JSON.stringify({
messageId: 12,
artifact: {
id: 'review-1',
type: 'review',
status: 'expired',
messageId: 12,
conversationId: 3,
payload: { id: 'review-1', title: '旧导入预览', status: 'expired', sections: [] },
},
}),
});
expect(message.uiArtifacts).toHaveLength(2);
expect(message.forms?.[0]).toMatchObject({ id: 'form-1', title: '新增学生' });
expect(message.reviews?.[0]).toMatchObject({ id: 'review-1', status: 'expired' });
});
it('stores ui.import_preflight in message metadata and restores it from completed message', () => {
const preflight = {
verdict: 'needs_input',