feat(web): AI 工作台意图规划与规划思考模型

- 新增 workbenchAiIntentPlannerModel,基于 LLM function_call 解析建单/草稿/提交意图,区分 model 与 rule_fallback 来源
- 新增 workbenchAiPlanningThinkingModel 合并规划思考事件流,按 eventId 去重合并
- application gate/preview 模型接入意图规划,usePersonalWorkbenchAiMode/useWorkbenchAiStewardFlow/useWorkbenchAiActionRouter 链路适配,支持上下文提交
- steward 服务与 stewardPlanModel 适配新动作结构,receipt-folder-view 微调样式
- 新增 intent-planner-model/application-context-submit/steward-actions-service 测试,更新 gate-model/action-router/plan-message-copy/fast-preview 测试
This commit is contained in:
caoxiaozhu
2026-06-24 21:58:46 +08:00
parent 5311c99d69
commit bc560145a4
18 changed files with 1914 additions and 38 deletions

View File

@@ -28,6 +28,13 @@ const AGENT_LABELS = {
expense: '报销助手'
}
const EXECUTABLE_STEWARD_ACTION_TYPES = new Set([
'save_application_draft',
'submit_application',
'create_reimbursement_draft',
'associate_attachments'
])
export function buildStewardPlanRequest({
rawText = '',
files = [],
@@ -102,10 +109,12 @@ export function normalizeStewardPlan(rawPlan = {}, options = {}) {
summary: String(item.summary || ''),
status: String(item.status || ''),
confidence: Number(item.confidence || 0),
requestedAction: String(item.requested_action || item.requestedAction || ''),
ontologyFields: item.ontology_fields || item.ontologyFields || {},
missingFields,
missingFieldItems: buildStewardFieldItems(missingFields, taskType),
confirmationRequired: item.confirmation_required ?? item.confirmationRequired ?? true
confirmationRequired: item.confirmation_required ?? item.confirmationRequired ?? true,
actionSteps: normalizeStewardActionSteps(item.action_steps || item.actionSteps)
}
})
: [],
@@ -137,6 +146,26 @@ export function normalizeStewardPlan(rawPlan = {}, options = {}) {
}
}
function normalizeStewardActionSteps(rawSteps = []) {
if (!Array.isArray(rawSteps)) {
return []
}
return rawSteps
.map((step) => ({
step_id: String(step?.step_id || step?.stepId || ''),
action_type: String(step?.action_type || step?.actionType || ''),
label: String(step?.label || ''),
target_task_id: String(step?.target_task_id || step?.targetTaskId || ''),
status: String(step?.status || 'planned'),
requires_confirmation: Boolean(step?.requires_confirmation ?? step?.requiresConfirmation),
depends_on: Array.isArray(step?.depends_on || step?.dependsOn)
? step.depends_on || step.dependsOn
: [],
payload: step?.payload && typeof step.payload === 'object' ? step.payload : {}
}))
.filter((step) => step.step_id && step.action_type)
}
export function buildStewardPlanMessageText(plan) {
const normalized = normalizeStewardPlan(plan)
if (isOffTopicPlan(normalized)) {
@@ -353,6 +382,7 @@ export function buildStewardSuggestedActions(plan) {
const targetSessionType = actionType === 'confirm_create_application'
? SESSION_TYPE_APPLICATION
: SESSION_TYPE_EXPENSE
const executableStep = resolveExecutableStewardActionStep(task)
return [
{
label: buildNextActionLabel(actionType, task),
@@ -372,6 +402,7 @@ export function buildStewardSuggestedActions(plan) {
steward_confirmation_id: String(action.confirmation_id || action.confirmationId || ''),
steward_plan_id: normalized.planId,
steward_next_task_id: task?.taskId || '',
...buildStewardExecuteActionPayload(executableStep, task),
steward_current_task: buildStewardTaskPayload(task),
steward_remaining_task_count: normalized.tasks.filter((item) => item.taskId !== task?.taskId).length,
steward_remaining_tasks: buildRemainingTaskPayload(normalized, task?.taskId)
@@ -380,6 +411,26 @@ export function buildStewardSuggestedActions(plan) {
]
}
function resolveExecutableStewardActionStep(task = null) {
const steps = Array.isArray(task?.actionSteps || task?.action_steps)
? task.actionSteps || task.action_steps
: []
return [...steps].reverse().find((step) => EXECUTABLE_STEWARD_ACTION_TYPES.has(String(step.action_type || step.actionType || ''))) || null
}
function buildStewardExecuteActionPayload(step, task) {
if (!step) {
return {}
}
return {
steward_execute_action: true,
steward_action_type: String(step.action_type || step.actionType || ''),
steward_action_step: step,
steward_action_requires_confirmation: Boolean(step.requires_confirmation ?? step.requiresConfirmation),
steward_action_task_id: task?.taskId || task?.task_id || ''
}
}
function normalizePendingFlowConfirmation(rawPlan = {}) {
const rawPending = rawPlan.pending_flow_confirmation || rawPlan.pendingFlowConfirmation || {}
const rawCandidates = Array.isArray(rawPlan.candidate_flows || rawPlan.candidateFlows)
@@ -779,7 +830,9 @@ function buildStewardTaskPayload(task) {
title: task.title || '',
summary: task.summary || '',
assigned_agent: task.assignedAgent || task.assigned_agent || '',
requested_action: task.requestedAction || task.requested_action || '',
ontology_fields: task.ontologyFields || task.ontology_fields || {},
missing_fields: task.missingFields || task.missing_fields || []
missing_fields: task.missingFields || task.missing_fields || [],
action_steps: task.actionSteps || task.action_steps || []
}
}