import { ASSISTANT_SCOPE_ACTION_SWITCH, } from '../../utils/assistantSessionScope.js' import { SESSION_TYPE_APPLICATION, SESSION_TYPE_EXPENSE } from './travelReimbursementConversationModel.js' const TASK_TYPE_LABELS = { expense_application: '费用申请', reimbursement: '费用报销' } const AGENT_LABELS = { application_assistant: '申请助手', reimbursement_assistant: '报销助手' } export function buildStewardPlanRequest({ rawText = '', files = [], currentUser = {} } = {}) { const safeFiles = Array.isArray(files) ? files : [] return { message: String(rawText || '').trim(), user_id: String(currentUser.username || currentUser.name || 'anonymous').trim() || 'anonymous', client_now_iso: new Date().toISOString(), attachments: safeFiles.map((file) => ({ name: String(file?.name || '').trim(), media_type: String(file?.type || '').trim() })).filter((item) => item.name), context_json: { entry_source: 'workbench', session_type: 'steward', role_codes: Array.isArray(currentUser.roleCodes) ? currentUser.roleCodes : [], username: currentUser.username || '', name: currentUser.name || currentUser.username || '', department_name: currentUser.departmentName || currentUser.department || '', employee_grade: currentUser.grade || '' } } } export function normalizeStewardPlan(rawPlan = {}, options = {}) { const visibleThinkingEventCount = Number.isFinite(options.visibleThinkingEventCount) ? Number(options.visibleThinkingEventCount) : Number(rawPlan.visibleThinkingEventCount || rawPlan.visible_thinking_event_count || 0) return { planId: String(rawPlan.plan_id || rawPlan.planId || ''), planStatus: String(rawPlan.plan_status || rawPlan.planStatus || ''), summary: String(rawPlan.summary || ''), visibleThinkingEventCount, thinkingEvents: Array.isArray(rawPlan.thinking_events) ? rawPlan.thinking_events.map((item) => ({ eventId: String(item.event_id || item.eventId || ''), stage: String(item.stage || ''), title: String(item.title || ''), content: String(item.content || ''), status: String(item.status || 'completed') })) : [], tasks: Array.isArray(rawPlan.tasks) ? rawPlan.tasks.map((item) => ({ taskId: String(item.task_id || item.taskId || ''), taskType: String(item.task_type || item.taskType || ''), taskTypeLabel: TASK_TYPE_LABELS[String(item.task_type || item.taskType || '')] || '财务任务', assignedAgent: String(item.assigned_agent || item.assignedAgent || ''), assignedAgentLabel: AGENT_LABELS[String(item.assigned_agent || item.assignedAgent || '')] || '财务助手', title: String(item.title || ''), summary: String(item.summary || ''), status: String(item.status || ''), confidence: Number(item.confidence || 0), ontologyFields: item.ontology_fields || item.ontologyFields || {}, missingFields: Array.isArray(item.missing_fields || item.missingFields) ? item.missing_fields || item.missingFields : [], confirmationRequired: item.confirmation_required ?? item.confirmationRequired ?? true })) : [], attachmentGroups: Array.isArray(rawPlan.attachment_groups) ? rawPlan.attachment_groups.map((item) => ({ groupId: String(item.group_id || item.groupId || ''), targetTaskId: String(item.target_task_id || item.targetTaskId || ''), scene: String(item.scene || ''), sceneLabel: String(item.scene_label || item.sceneLabel || ''), attachmentNames: Array.isArray(item.attachment_names || item.attachmentNames) ? item.attachment_names || item.attachmentNames : [], excludedAttachmentNames: Array.isArray(item.excluded_attachment_names || item.excludedAttachmentNames) ? item.excluded_attachment_names || item.excludedAttachmentNames : [], confidence: Number(item.confidence || 0), rationale: String(item.rationale || ''), confirmationRequired: item.confirmation_required ?? item.confirmationRequired ?? true })) : [], confirmationGroups: Array.isArray(rawPlan.confirmation_groups) ? rawPlan.confirmation_groups : [] } } export function buildStewardPlanMessageText(plan) { const normalized = normalizeStewardPlan(plan) const taskLines = normalized.tasks.map((task, index) => `${index + 1}. ${task.title || task.taskTypeLabel},交给${task.assignedAgentLabel}。` ) return [ '**小财管家已完成任务拆解。**', '', normalized.summary || `我识别到 ${normalized.tasks.length} 个待处理任务,请确认后继续执行。`, '', ...taskLines ].join('\n') } export function buildStewardSuggestedActions(plan) { const normalized = normalizeStewardPlan(plan) const taskById = new Map(normalized.tasks.map((task) => [task.taskId, task])) const groupById = new Map(normalized.attachmentGroups.map((group) => [group.groupId, group])) return normalized.confirmationGroups.map((action) => { const actionType = String(action.action_type || action.actionType || '').trim() const taskId = String(action.target_task_id || action.targetTaskId || '').trim() const groupId = String(action.attachment_group_id || action.attachmentGroupId || '').trim() const task = taskById.get(taskId) const group = groupById.get(groupId) const targetSessionType = actionType === 'confirm_create_application' ? SESSION_TYPE_APPLICATION : SESSION_TYPE_EXPENSE return { label: String(action.label || '确认继续处理'), description: String(action.description || ''), icon: actionType === 'confirm_create_application' ? 'mdi mdi-file-plus-outline' : actionType === 'confirm_attachment_group' ? 'mdi mdi-folder-check-outline' : 'mdi mdi-receipt-text-plus-outline', action_type: ASSISTANT_SCOPE_ACTION_SWITCH, payload: { session_type: targetSessionType, carry_text: buildStewardCarryText(actionType, task, group), carry_files: actionType !== 'confirm_create_application', auto_submit: true, steward_confirmation_id: String(action.confirmation_id || action.confirmationId || ''), steward_plan_id: normalized.planId } } }) } function buildStewardCarryText(actionType, task, group) { if (actionType === 'confirm_attachment_group' && group) { return [ `我确认将以下附件归集为${group.sceneLabel || '当前报销任务'},请继续整理报销核对信息。`, `附件:${group.attachmentNames.join('、') || '待确认'}`, group.excludedAttachmentNames.length ? `暂不归集:${group.excludedAttachmentNames.join('、')}` : '' ].filter(Boolean).join('\n') } if (!task) { return '我确认继续处理这项财务任务,请按现有流程核对信息。' } const fields = Object.entries(task.ontologyFields || {}) .filter(([, value]) => String(value || '').trim()) .map(([key, value]) => `${key}: ${value}`) return [ `我确认处理“小财管家”识别的任务:${task.title || task.taskTypeLabel}。`, task.summary ? `任务摘要:${task.summary}` : '', fields.length ? `本体字段:${fields.join(';')}` : '', task.missingFields.length ? `待补充字段:${task.missingFields.join('、')}` : '', '请按现有流程生成核对结果,并在需要入库、绑定附件或提交审批前让我再次确认。' ].filter(Boolean).join('\n') }