139 lines
5.2 KiB
Python
139 lines
5.2 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from app.schemas.steward import (
|
||
|
|
StewardCandidateFlow,
|
||
|
|
StewardFlowStatePatch,
|
||
|
|
StewardPendingFlowConfirmation,
|
||
|
|
StewardPlanResponse,
|
||
|
|
)
|
||
|
|
from app.services.steward_flow_state import StewardFlowStateService
|
||
|
|
|
||
|
|
|
||
|
|
def test_state_merge_keeps_application_and_reimbursement_flows() -> None:
|
||
|
|
service = StewardFlowStateService()
|
||
|
|
|
||
|
|
state = service.merge_state(
|
||
|
|
{},
|
||
|
|
StewardFlowStatePatch(
|
||
|
|
active_flow="travel_application",
|
||
|
|
flow_id="travel_application",
|
||
|
|
intent="travel_application_create",
|
||
|
|
fields={"expense_type": "travel", "location": "上海", "reason": "客户现场支撑"},
|
||
|
|
missing_fields=["transport_mode"],
|
||
|
|
),
|
||
|
|
)
|
||
|
|
state = service.merge_state(
|
||
|
|
state,
|
||
|
|
StewardFlowStatePatch(
|
||
|
|
active_flow="travel_reimbursement",
|
||
|
|
flow_id="travel_reimbursement",
|
||
|
|
intent="travel_reimbursement_draft",
|
||
|
|
fields={"amount": "708.00", "invoice_no": "NO-1"},
|
||
|
|
linked_application_claim_id="claim-app-001",
|
||
|
|
),
|
||
|
|
)
|
||
|
|
|
||
|
|
assert state["active_flow"] == "travel_reimbursement"
|
||
|
|
assert state["flows"]["travel_application"]["fields"]["location"] == "上海"
|
||
|
|
assert state["flows"]["travel_application"]["missing_fields"] == ["transport_mode"]
|
||
|
|
assert state["flows"]["travel_reimbursement"]["fields"]["amount"] == "708.00"
|
||
|
|
assert state["flows"]["travel_reimbursement"]["linked_application_claim_id"] == "claim-app-001"
|
||
|
|
|
||
|
|
|
||
|
|
def test_state_merge_filters_non_ontology_fields() -> None:
|
||
|
|
service = StewardFlowStateService()
|
||
|
|
|
||
|
|
state = service.merge_state(
|
||
|
|
{},
|
||
|
|
StewardFlowStatePatch(
|
||
|
|
active_flow="travel_application",
|
||
|
|
flow_id="travel_application",
|
||
|
|
intent="travel_application_create",
|
||
|
|
fields={
|
||
|
|
"location": "上海",
|
||
|
|
"invented_field": "x",
|
||
|
|
"occurred_date": "2026-06-15",
|
||
|
|
},
|
||
|
|
),
|
||
|
|
)
|
||
|
|
|
||
|
|
assert state["flows"]["travel_application"]["fields"] == {
|
||
|
|
"location": "上海",
|
||
|
|
"time_range": "2026-06-15",
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
def test_state_merge_appends_traceable_events() -> None:
|
||
|
|
service = StewardFlowStateService()
|
||
|
|
|
||
|
|
state = service.merge_state(
|
||
|
|
{},
|
||
|
|
StewardFlowStatePatch(
|
||
|
|
active_flow="travel_application",
|
||
|
|
flow_id="travel_application",
|
||
|
|
intent="travel_application_create",
|
||
|
|
fields={"location": "北京"},
|
||
|
|
evidence=[{"source": "user_message", "field": "location", "text": "去北京出差"}],
|
||
|
|
),
|
||
|
|
)
|
||
|
|
|
||
|
|
assert len(state["events"]) == 1
|
||
|
|
assert state["events"][0]["flow_id"] == "travel_application"
|
||
|
|
assert state["events"][0]["intent"] == "travel_application_create"
|
||
|
|
assert state["events"][0]["fields"] == {"location": "北京"}
|
||
|
|
assert state["events"][0]["evidence"][0]["text"] == "去北京出差"
|
||
|
|
|
||
|
|
|
||
|
|
def test_state_merge_plan_keeps_pending_flow_confirmation() -> None:
|
||
|
|
service = StewardFlowStateService()
|
||
|
|
|
||
|
|
state = service.merge_plan(
|
||
|
|
{},
|
||
|
|
StewardPlanResponse(
|
||
|
|
plan_id="steward_plan_pending",
|
||
|
|
plan_status="needs_flow_confirmation",
|
||
|
|
planning_source="llm_function_call",
|
||
|
|
next_action="confirm_flow",
|
||
|
|
summary="需要先确认是申请还是报销。",
|
||
|
|
pending_flow_confirmation=StewardPendingFlowConfirmation(
|
||
|
|
status="pending",
|
||
|
|
source_message="2月20-23日去上海出差辅助国网仿生产环境部署",
|
||
|
|
reason="缺少申请或报销动作词。",
|
||
|
|
candidate_flows=[
|
||
|
|
StewardCandidateFlow(
|
||
|
|
flow_id="travel_application",
|
||
|
|
label="补办出差申请",
|
||
|
|
confidence=0.52,
|
||
|
|
reason="可能是补办申请。",
|
||
|
|
ontology_fields={
|
||
|
|
"time_range": "2026-02-20",
|
||
|
|
"location": "上海",
|
||
|
|
"expense_type": "travel",
|
||
|
|
"reason": "辅助国网仿生产环境部署",
|
||
|
|
},
|
||
|
|
missing_fields=["transport_mode"],
|
||
|
|
),
|
||
|
|
StewardCandidateFlow(
|
||
|
|
flow_id="travel_reimbursement",
|
||
|
|
label="发起费用报销",
|
||
|
|
confidence=0.48,
|
||
|
|
reason="可能是发起报销。",
|
||
|
|
ontology_fields={
|
||
|
|
"time_range": "2026-02-20",
|
||
|
|
"location": "上海",
|
||
|
|
"expense_type": "travel",
|
||
|
|
"reason": "辅助国网仿生产环境部署",
|
||
|
|
},
|
||
|
|
),
|
||
|
|
],
|
||
|
|
),
|
||
|
|
),
|
||
|
|
)
|
||
|
|
|
||
|
|
assert state["active_flow"] == ""
|
||
|
|
assert state["pending_flow_confirmation"]["status"] == "pending"
|
||
|
|
assert state["flows"]["travel_application"]["status"] == "pending_flow_confirmation"
|
||
|
|
assert state["flows"]["travel_application"]["fields"]["location"] == "上海"
|
||
|
|
assert state["flows"]["travel_application"]["missing_fields"] == ["transport_mode"]
|
||
|
|
assert state["flows"]["travel_reimbursement"]["fields"]["time_range"] == "2026-02-20"
|