feat: 增强差旅报销审核流程与票据智能推理
优化本体解析和编排器的差旅场景处理能力,完善报销单草稿 保存和费用明细同步逻辑,前端报销创建页面增加行程推理和 票据审核交互,新增助手会话快照工具函数,补充单元测试。
This commit is contained in:
@@ -496,25 +496,18 @@ def test_user_agent_guides_generic_expense_request() -> None:
|
||||
)
|
||||
)
|
||||
|
||||
assert response.review_payload is not None
|
||||
assert response.answer == response.review_payload.body_message
|
||||
assert response.review_payload.can_proceed is False
|
||||
assert response.review_payload.missing_slots == [
|
||||
"报销类型",
|
||||
"发生时间",
|
||||
"金额",
|
||||
"事由说明",
|
||||
"票据附件",
|
||||
]
|
||||
assert [item.action_type for item in response.review_payload.confirmation_actions] == [
|
||||
"cancel_review",
|
||||
"edit_review",
|
||||
assert response.review_payload is None
|
||||
assert response.draft_payload is None
|
||||
assert "请先在下面选择报销场景" in response.answer
|
||||
assert [item.action_type for item in response.suggested_actions] == [
|
||||
"select_expense_type",
|
||||
"select_expense_type",
|
||||
"select_expense_type",
|
||||
"select_expense_type",
|
||||
"select_expense_type",
|
||||
"select_expense_type",
|
||||
]
|
||||
edit_action = next(
|
||||
item for item in response.review_payload.confirmation_actions if item.action_type == "edit_review"
|
||||
)
|
||||
assert edit_action.label == "选择报销类型"
|
||||
assert edit_action.emphasis == "primary"
|
||||
assert [item.label for item in response.suggested_actions[:3]] == ["差旅费", "交通费", "住宿费"]
|
||||
|
||||
|
||||
def test_user_agent_asks_for_type_when_trip_context_is_ambiguous() -> None:
|
||||
@@ -537,25 +530,69 @@ def test_user_agent_asks_for_type_when_trip_context_is_ambiguous() -> None:
|
||||
)
|
||||
)
|
||||
|
||||
assert response.review_payload is None
|
||||
assert response.draft_payload is None
|
||||
assert "请先在下面选择报销场景" in response.answer
|
||||
assert "避免系统先入为主" in response.answer
|
||||
assert [item.label for item in response.suggested_actions] == [
|
||||
"差旅费",
|
||||
"交通费",
|
||||
"住宿费",
|
||||
"业务招待费",
|
||||
"办公费",
|
||||
"其他费用",
|
||||
]
|
||||
assert response.suggested_actions[0].payload["original_message"] == message
|
||||
|
||||
|
||||
def test_user_agent_continues_identification_after_expense_type_selection() -> None:
|
||||
session_factory = build_session_factory()
|
||||
with session_factory() as db:
|
||||
message = "业务发生时间:2026-02-20 至 2026-02-23,去上海支持上海电力部署项目,申请报销"
|
||||
ontology = SemanticOntologyService(db).parse(
|
||||
OntologyParseRequest(
|
||||
query=f"{message}\n用户选择报销场景:差旅费",
|
||||
user_id="pytest-selected-type@example.com",
|
||||
context_json={
|
||||
"expense_scene_selection": {
|
||||
"expense_type": "travel",
|
||||
"expense_type_label": "差旅费",
|
||||
"original_message": message,
|
||||
},
|
||||
"review_form_values": {
|
||||
"expense_type": "差旅费",
|
||||
},
|
||||
"user_input_text": message,
|
||||
},
|
||||
)
|
||||
)
|
||||
response = UserAgentService(db).respond(
|
||||
UserAgentRequest(
|
||||
run_id=ontology.run_id,
|
||||
user_id="pytest-selected-type@example.com",
|
||||
message=f"{message}\n用户选择报销场景:差旅费",
|
||||
ontology=ontology,
|
||||
context_json={
|
||||
"expense_scene_selection": {
|
||||
"expense_type": "travel",
|
||||
"expense_type_label": "差旅费",
|
||||
"original_message": message,
|
||||
},
|
||||
"review_form_values": {
|
||||
"expense_type": "差旅费",
|
||||
},
|
||||
"user_input_text": message,
|
||||
},
|
||||
tool_payload={"draft_only": True},
|
||||
)
|
||||
)
|
||||
|
||||
assert response.review_payload is not None
|
||||
slot_map = {item.key: item for item in response.review_payload.slot_cards}
|
||||
assert slot_map["expense_type"].value == ""
|
||||
assert slot_map["expense_type"].status == "missing"
|
||||
assert slot_map["expense_type"].value == "差旅费"
|
||||
assert slot_map["expense_type"].normalized_value == "travel"
|
||||
assert slot_map["time_range"].value == "2026-02-20 至 2026-02-23"
|
||||
assert slot_map["location"].value == "上海"
|
||||
assert response.review_payload.can_proceed is False
|
||||
assert "报销类型" in response.review_payload.missing_slots
|
||||
assert "选择报销类型" in response.review_payload.body_message
|
||||
assert "不会重新改判报销类型" in response.review_payload.body_message
|
||||
edit_action = next(
|
||||
item for item in response.review_payload.confirmation_actions if item.action_type == "edit_review"
|
||||
)
|
||||
assert edit_action.label == "选择报销类型"
|
||||
assert edit_action.emphasis == "primary"
|
||||
assert [item.action_type for item in response.review_payload.confirmation_actions] == [
|
||||
"cancel_review",
|
||||
"edit_review",
|
||||
]
|
||||
|
||||
|
||||
def test_user_agent_guides_implicit_expense_draft_request() -> None:
|
||||
|
||||
Reference in New Issue
Block a user