Files
X-Financial/document/development/2026-06-26/dev-logs/bugs/multi-task-reimbursement-not-starting.md
caoxiaozhu 08f023243e fix(web): 多 task 草稿自动保存后继续推进下一 task
useWorkbenchAiApplicationPreviewFlow 在自动保存草稿分支透传 onApplicationActionCompleted,
确保草稿/提交完成后仍能按 remaining tasks 推进,修复多 task 报销场景后续步骤不启动。
更新 application-context-submit/intent-planner-model 测试,补充 bug 日志与开发日志。
2026-06-29 20:17:36 +08:00

38 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 多 task 串行推进时 task2(业务招待费报销)无法启动
## 修复记录
- 12:14记录 bug 修复:多 task 串行推进时task1出差申请做完后点击"继续处理费用报销"task2业务招待费报销根本无法启动报销草稿交互不起来task2 语义(招待费/2000元/昨天)全部丢失。
- Git 提交检查:`git fetch --all --prune` 因远端 SSL 连接失败未拉到新内容;`HEAD..@{u}` 为空(无 upstream 新提交);`@{u}..HEAD` 本地领先 8 个提交,其中与本 bug 相关的前置提交为 `3a5664c4 feat(web): 多 task 串行推进``3e4b1e15 fix(web): 保存草稿/提交成功后也推进到下一个 task``43c3ff86 fix(web): steward plan 确认按钮直接拉起申请预览,不丢失 remaining tasks`
- 修改:
- `web/src/composables/workbenchAiMode/useWorkbenchAiActionRouter.js``travel_reimbursement` 分支不再硬编码 `requiresApplicationBeforeReimbursement=true`,改为从 `steward_current_task.ontology_fields` 解析费用类型并调 `requiresApplicationBeforeReimbursement(expenseType)` 判断;用 `buildAiExpenseDraftPrefillValues` 把 task 语义(金额/时间/事由/地点)预填进报销草稿;透传 `steward_remaining_tasks``ai_application_start_inline` 分支也透传 `prefill_values``steward_remaining_tasks`,让"查不到申请单→发起申请单"后能回到 task2。`buildNextTaskSuggestedAction` payload 补 `steward_remaining_tasks: remainingTasks.slice(1)`,防 3+ task 断链。
- `web/src/composables/workbenchAiMode/useWorkbenchAiExpenseFlow.js``startAiExpenseDraft` 扩展第 4 参 `options``prefillValues`/`stewardRemainingTasks``resolveAiExpenseApplicationLink` 接收 options查不到申请单时按费用类型动态生成"确认发起业务招待申请"按钮(不再写死"出差申请"),并透传 `prefill_values`/`steward_remaining_tasks`;新增 `attachStewardRemainingTasks`/`resolveStewardRemainingTasks`/`resolveRequiredApplicationLabel`/`buildExpenseDraftNextTaskAction` helper把 remaining tasks 上下文挂在 draft 上贯穿报销→关联申请单→pollLinkedDraftJob 全流程;`advanceAiExpenseDraft``linkAiExpenseApplication``replaceInlineAssistantMessage``resumePendingLinkedReimbursementDraftJobs` 均补 remaining tasks 透传。
- `web/src/composables/workbenchAiMode/useWorkbenchAiApplicationPreviewFlow.js``buildApplicationPreviewNextTaskAction` payload 补 `steward_remaining_tasks: remainingTasks.slice(1)`
- `web/src/utils/aiExpenseDraftModel.js``createAiExpenseDraft` 新增第三参 `prefillValues`,按已填值推进 `stepKey` 到第一个未填字段;新增 `buildAiExpenseDraftPrefillValues` 把 task ontology 映射到草稿字段。
- `web/src/composables/workbenchAiMode/workbenchAiMessageModel.js``createInlineMessage`/`normalizeRuntimeMessage`/`serializeRuntimeMessage` 三处补 `stewardRemainingTasks` 字段读写,避免消息重建/刷新丢失推进上下文。
- `web/src/utils/aiWorkbenchConversationStore.js``normalizeMessage` 持久化时保留 `stewardRemainingTasks`
- 操作:未提交(工作区有大量预先存在的未提交改动,未自动提交)。容器 `local-x-financial-linux` 此前未运行,已 `docker start` 恢复。
- 验证在容器内node v22.22.3)跑 `node --test tests/ai-expense-draft-model.test.mjs tests/ai-workbench-conversation-store.test.mjs tests/workbench-ai-action-router.test.mjs`16 个测试全部通过(含新增的 `buildAiExpenseDraftPrefillValues``createAiExpenseDraft` 预填、`stewardRemainingTasks` 持久化、`travel_reimbursement` 分支预填+透传 4 个用例。其余前端测试失败为基线已存在git stash 对比确认,与本次改动无关,多为正则匹配源码文本的断言因工作区其他未提交改动而失败)。
- 影响:用户一次提问含"出差申请 + 招待费报销"等多 task 时task1 完成后 task2 现在能正常启动招待费类型、2000元金额、时间、事由会预填到报销草稿招待费需要前置招待申请单业务规则保留查不到时按钮文案按类型动态展示并承接语义发起申请单后能回到 task23+ task 不再断链;刷新会话后推进上下文不丢失。
- 12:23继续修复同一 bug模型计划已经返回“出差申请 + 业务招待费报销”两个 task 时AI 工作台入口只消费第一个申请 task第二个 task 没有自动开始。
- Git 提交检查:`git fetch --all --prune` 仍因 `LibreSSL SSL_connect: SSL_ERROR_SYSCALL` 失败;`HEAD..@{u}` 为空,未发现可见 upstream 新提交;`@{u}..HEAD` 本地领先 8 个提交:`43c3ff86 fix(web): steward plan 确认按钮直接拉起申请预览,不丢失 remaining tasks``3e4b1e15 fix(web): 保存草稿/提交成功后也推进到下一个 task``3a5664c4 feat(web): 多 task 串行推进 - task1 完成后自动展示 task2 确认按钮``d139a63e refactor(server): 意图识别改 LLM 驱动,规则只做闲聊拦截+resume 兜底``8a2ae6eb fix(server): gate_classify 复用 _classify_irrelevant_input 修复 off_topic 误杀``992cf71f refactor(server): Phase 1 图拓扑重构 - LangGraph 成为唯一编排者``54356ba8 refactor(server): scene 注册表骨架 + 统一门控管道设计文档``e9d7c56d feat(server): 会话上下文保留LLM 历史 + 确定性兜底双保险)`
- 修改:`workbenchAiIntentPlannerModel.js` 在归一化模型计划时保留 application task 后面的 `stewardRemainingTasks`,并只在存在剩余 task 时放进可执行申请请求;`usePersonalWorkbenchAiMode.js` 把 remaining tasks 传入申请预览,并在预览生成后通过现有 `steward_continue_next_task` 路由自动启动下一个 task低置信确认按钮 payload 也继续携带队列;`useWorkbenchAiApplicationPreviewFlow.js` 在普通申请预览完成后调用 `onPreviewReadyForNextTask``useWorkbenchAiActionRouter.js``ai_application_confirm_intent` 分支同样透传 remaining tasks 并注册自动续跑回调。
- 操作:新增回归测试覆盖“模型返回申请 task + 业务招待报销 task 时,前端可执行请求保留第二个 task”以及“低置信确认按钮不丢队列并提供自动续跑回调”保留既有未提交工作区改动没有回滚或提交其他文件。
- 验证:先看到新增测试红灯(`plan.stewardRemainingTasks``undefined`,确认按钮 options 也没有 remaining tasks修复后 `node --test web/tests/workbench-ai-intent-planner-model.test.mjs web/tests/workbench-ai-action-router.test.mjs` 通过 24/24`git diff --check` 通过;`docker exec -w /app -e SERVER_VENV_DIR=/tmp/x-financial-server-venv x-financial-local-linux timeout 60s /tmp/x-financial-server-venv/bin/pytest -q server/tests/test_steward_planner.py -k 'future_travel_without_apply_word_as_application or uses_llm_for_multi_financial_demands'` 通过 2/2同命令在 `local-x-financial-linux` 收集阶段因该容器缺 `langgraph` 失败,已改用当前映射 5173 的 `x-financial-local-linux` 验证;`npm --prefix web run build` 通过;真实 `http://localhost:5173/api/v1/steward/plans` 采样确认该用户句子返回 `expense_application``reimbursement` 两个 task。
- 影响用户输入“2月20-23日去上海出差3天服务国网服务器部署并且报销昨天的业务招待费2000元”时前端不再在第一个申请预览处截断队列申请预览生成后会自动把第二个业务招待费报销 task 交给现有报销流程继续处理,同时刷新/低置信确认路径也不丢 task 队列。
- 22:30继续修复同一 bug用户点击“保存草稿”后task1 已经完成,但界面仍只展示“继续处理费用报销”按钮,没有自动开始 task2。
- Git 提交检查:`git fetch --all --prune` 仍因 `LibreSSL SSL_connect: SSL_ERROR_SYSCALL` 失败;`HEAD..@{u}` 为空,未发现可见 upstream 新提交;`@{u}..HEAD` 本地仍领先 8 个提交:`43c3ff86``3e4b1e15``3a5664c4``d139a63e``8a2ae6eb``992cf71f``54356ba8``e9d7c56d`
- 修改:`useWorkbenchAiApplicationPreviewFlow.js` 在保存草稿/提交申请成功后,如果当前申请消息还有 `stewardRemainingTasks`,就调用 `onApplicationActionCompleted` 自动续跑下一项;自动续跑时结果消息只保留查看详情动作,不再额外保留“继续处理”按钮,避免重复触发同一个 task。`usePersonalWorkbenchAiMode.js` 将该回调接到 `startModelPlannedNextTask``useWorkbenchAiActionRouter.js` 的低置信确认路径也同步传入保存/提交成功回调。
- 操作:先补红灯断言,要求工作台入口向申请预览流传 `onApplicationActionCompleted`,且申请预览流在保存/提交成功分支调用该回调;然后按同一条 `steward_continue_next_task` 路由复用原有报销启动逻辑。
- 验证:红灯阶段 `node --test web/tests/workbench-ai-intent-planner-model.test.mjs` 失败在缺少 `onApplicationActionCompleted`;修复后 `node --test web/tests/workbench-ai-intent-planner-model.test.mjs` 17/17 通过,`node --test web/tests/workbench-ai-action-router.test.mjs` 7/7 通过;`git diff --check` 通过;`npm --prefix web run build` 通过。
- 影响:复合任务里用户保存第一张出差申请草稿后,系统会立即进入第二个业务招待费报销任务,不再要求用户手动点击“继续处理费用报销”;低置信确认后再保存草稿也保持同样行为。
- 22:45继续修复同一 bug真实页面已经显示“申请草稿已保存”但保存动作结束后没有继续拉起第二个业务招待费报销 task。
- Git 提交检查:`git fetch --all --prune` 仍因 `LibreSSL SSL_connect: SSL_ERROR_SYSCALL` 失败;`HEAD..@{u}` 为空,未发现可见 upstream 新提交;`@{u}..HEAD` 本地领先 13 个提交:`6bdaeed6 chore: 忽略 .zcode 本地目录并更新规则表与开发日志``d5a8f847 refactor(web): 应用外壳/差旅详情/报销创建视图适配主题与多 task``c4b5fcc0 feat(web): AI 工作台多 task 串行推进与会话适配``5753899e feat(web): 主题皮肤系统与 LLM 设置面板重构``9c3fa80d feat(server): 设置持久化新增 LLM 模型表与主题字段`,以及前面记录过的 8 个本地 ahead 提交。
- 修改:`useWorkbenchAiApplicationPreviewFlow.js` 在保存草稿/提交申请成功分支新增 `actionCompletedHandler`,优先使用本次 `executeInlineApplicationPreviewAction` / `startAiApplicationPreview` options 传入的 `onApplicationActionCompleted`,没有时再回落到 composable 初始化回调;自动保存草稿时同步把 `options.onApplicationActionCompleted` 透传给保存动作。`workbench-ai-application-context-submit.test.mjs` 新增“自动保存申请草稿后继续剩余 steward task”的行为测试`workbench-ai-intent-planner-model.test.mjs` 更新结构断言,锁住 options 回调优先和自动保存透传契约。
- 操作:先用新增测试复现红灯:自动保存时确实只触发初始化回调,`options` 里的续跑回调没有被使用;再做最小修复,让保存动作按本次调用上下文续跑下一任务。
- 验证:红灯阶段 `node --test web/tests/workbench-ai-application-context-submit.test.mjs` 失败在 `fromOptions``undefined`;修复后该测试 2/2 通过;`node --test web/tests/workbench-ai-intent-planner-model.test.mjs` 17/17 通过;`node --test web/tests/workbench-ai-action-router.test.mjs` 7/7 通过;真实 `http://127.0.0.1:5173/api/v1/steward/plans` 采样确认该用户句子仍返回 `expense_application` + `reimbursement` 两个 task`npm --prefix web run build` 通过;`git diff --check` 通过。
- 影响:保存草稿结果消息到达后,前端会使用当前任务链路传下来的续跑回调立即处理剩余 task用户截图里的“申请草稿已保存”不再是终点后续业务招待费报销会自动进入现有报销流程。