feat(web): AI 工作台多 task 串行推进与会话适配

- useWorkbenchAiApplicationPreviewFlow/useWorkbenchAiActionRouter/useWorkbenchAiCommandIntents 支持 task1 完成后自动推进 task2,确认按钮直接拉起申请预览,草稿/提交成功后继续推进下一 task
- workbenchAiIntentPlannerModel/workbenchAiMessageModel/workbenchAiCommandIntentModel 适配多 task 意图规划与消息结构
- aiApplicationPreviewActions/aiApplicationPrecheckModel/aiExpenseDraftModel/aiWorkbenchConversationStore 草稿与会话存储适配
- PersonalWorkbenchAiMode 与样式适配,更新 preview-actions/expense-draft/conversation-store/fast-preview/action-router/command-intent/intent-planner 测试
This commit is contained in:
caoxiaozhu
2026-06-26 22:42:23 +08:00
parent 5753899eb3
commit c4b5fcc067
22 changed files with 1171 additions and 144 deletions

View File

@@ -79,6 +79,48 @@ test('workbench AI intent planner normalizes model travel application submit pla
})
})
test('workbench AI intent planner keeps reimbursement task after first application task', () => {
const reimbursementTask = {
task_id: 'task-reimbursement-2',
task_type: 'reimbursement',
assigned_agent: 'reimbursement_assistant',
title: '业务招待费报销',
summary: '报销昨天的业务招待费 2000 元',
requested_action: 'preview',
confidence: 0.9,
ontology_fields: {
expense_type: 'entertainment',
expense_type_label: '业务招待费',
time_range: '2026-06-25',
amount: '2000元',
reason: '业务招待'
},
missing_fields: []
}
const plan = normalizeWorkbenchAiIntentPlan({
planning_source: 'llm_function_call',
tasks: [{
task_id: 'task-application-1',
task_type: 'expense_application',
assigned_agent: 'application_assistant',
requested_action: 'preview',
confidence: 0.93,
ontology_fields: {
expense_type: 'travel',
time_range: '2026-02-20 至 2026-02-23',
location: '上海',
reason: '服务国网服务器部署'
},
missing_fields: ['transport_mode']
}, reimbursementTask]
}, {
prompt: '2月20-23日去上海出差3天服务国网服务器部署并且报销昨天的业务招待费2000元'
})
assert.deepEqual(plan.stewardRemainingTasks, [reimbursementTask])
assert.deepEqual(resolveExecutableTravelApplicationPlan(plan).stewardRemainingTasks, [reimbursementTask])
})
test('workbench AI intent planner prefers server action steps when present', () => {
const plan = normalizeWorkbenchAiIntentPlan({
planning_source: 'llm_function_call',
@@ -304,7 +346,12 @@ test('workbench AI mode asks steward model plan before fallback execution', () =
assert.match(personalWorkbenchAiModeScript, /requestedSubmit:\s*travelApplicationRequest\.requestedSubmit/)
assert.match(personalWorkbenchAiModeScript, /submitRequiresConfirmation:\s*travelApplicationRequest\.submitRequiresConfirmation/)
assert.match(personalWorkbenchAiModeScript, /ontologyFields:\s*travelApplicationRequest\.ontologyFields/)
assert.match(personalWorkbenchAiModeScript, /stewardRemainingTasks:\s*travelApplicationRequest\.stewardRemainingTasks/)
assert.match(personalWorkbenchAiModeScript, /onPreviewReadyForNextTask:\s*startModelPlannedNextTask/)
assert.match(personalWorkbenchAiModeScript, /onApplicationActionCompleted:\s*startModelPlannedNextTask/)
assert.match(applicationPreviewFlowScript, /options\.autoSaveDraft/)
assert.match(applicationPreviewFlowScript, /options\.onPreviewReadyForNextTask/)
assert.match(applicationPreviewFlowScript, /onApplicationActionCompleted\(\s*targetMessage\.stewardRemainingTasks/)
assert.doesNotMatch(applicationPreviewFlowScript, /options\.autoSubmit && normalizeApplicationPreview\(preview\)\.readyToSubmit/)
assert.match(applicationPreviewFlowScript, /ontologyFields:\s*options\.ontologyFields/)
assert.match(applicationPreviewFlowScript, /executeInlineApplicationPreviewAction\(AI_APPLICATION_ACTION_SAVE_DRAFT/)