refactor(server): user_agent/steward/ocr 等服务重构并适配关联任务
- user_agent 拆分 application/locations/knowledge/response/review 四个子模块,接入申请位置语义与关联草稿分支 - steward planner/runtime/slot/plan_builder 决策链路重构,travel_reimbursement_calculator/orchestrator_expense_query 适配 - ocr/document_preview/document_intelligence/receipt_folder 复用预览与资产缓存,expense_claim_draft_flow/application_handoff 适配 - pyproject.toml 新增依赖,paddleocr bootstrap 脚本与 server_start.sh 调整 - 更新差旅/交通/通信等财务规则表,同步 document_intelligence/ocr/receipt_folder/user_agent 等测试
This commit is contained in:
@@ -15,6 +15,7 @@ from app.models.financial_record import ExpenseClaim
|
||||
from app.schemas.ontology import OntologyParseRequest
|
||||
from app.schemas.user_agent import UserAgentCitation, UserAgentRequest, UserAgentReviewRiskBrief
|
||||
from app.services.agent_assets import AgentAssetService
|
||||
from app.services.application_location_semantics import resolve_jieba_tokens
|
||||
from app.services.ontology import SemanticOntologyService
|
||||
from app.services.user_agent import UserAgentService
|
||||
from app.services.user_agent_documents import UserAgentDocumentService
|
||||
@@ -763,6 +764,67 @@ def test_user_agent_application_submit_blocks_overlapping_travel_dates() -> None
|
||||
assert response.draft_payload is None
|
||||
|
||||
|
||||
def test_user_agent_application_submit_normalizes_location_mixed_with_business_content() -> None:
|
||||
session_factory = build_session_factory()
|
||||
with session_factory() as db:
|
||||
response = build_application_user_agent_response(
|
||||
db,
|
||||
"确认提交",
|
||||
context_overrides={
|
||||
"manager_name": "向万红",
|
||||
"application_preview": {
|
||||
"fields": {
|
||||
"applicationType": "差旅费用申请",
|
||||
"time": "2026-02-20 至 2026-02-23",
|
||||
"location": "上海辅助国网仿生产服务器",
|
||||
"reason": "辅助国网仿生产服务器部署",
|
||||
"days": "4天",
|
||||
"transportMode": "火车",
|
||||
"amount": "2120元",
|
||||
}
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
claim = application_claim_query(db).one()
|
||||
assert claim.location == "上海市"
|
||||
assert claim.reason == "辅助国网仿生产服务器部署"
|
||||
assert "申请单据已生成" in response.answer
|
||||
assert response.draft_payload is not None
|
||||
|
||||
|
||||
def test_user_agent_application_submit_splits_location_and_reason_from_raw_sentence() -> None:
|
||||
session_factory = build_session_factory()
|
||||
with session_factory() as db:
|
||||
response = build_application_user_agent_response(
|
||||
db,
|
||||
"确认提交",
|
||||
history=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": "2026-02-20 至 2026-02-23,去上海辅助国网仿生产服务器部署,火车",
|
||||
}
|
||||
],
|
||||
context_overrides={
|
||||
"manager_name": "向万红",
|
||||
"grade": "P5",
|
||||
"department_name": "技术部",
|
||||
},
|
||||
)
|
||||
|
||||
claim = application_claim_query(db).one()
|
||||
assert claim.location == "上海市"
|
||||
assert claim.reason == "辅助国网仿生产服务器部署"
|
||||
assert "申请单据已生成" in response.answer
|
||||
|
||||
|
||||
def test_application_sentence_jieba_tokenizer_recognizes_location_boundary() -> None:
|
||||
tokens = resolve_jieba_tokens("上海辅助国网仿生产服务器部署")
|
||||
|
||||
assert ("上海", "ns") in tokens
|
||||
assert [word for word, _ in tokens] == ["上海", "辅助", "国网", "仿生产", "服务器", "部署"]
|
||||
|
||||
|
||||
def test_user_agent_application_maps_preview_travel_type_label() -> None:
|
||||
session_factory = build_session_factory()
|
||||
with session_factory() as db:
|
||||
@@ -2155,7 +2217,7 @@ def test_user_agent_returns_draft_limit_message_when_save_is_blocked() -> None:
|
||||
context_json={"review_action": "save_draft"},
|
||||
tool_payload={
|
||||
"draft_limit_reached": True,
|
||||
"message": "你当前已保存 3 个草稿,请先完成已保存的草稿,才能再次新建草稿。",
|
||||
"message": "您当前已保存 3 个草稿,请先完成已保存的草稿,才能再次新建草稿。",
|
||||
"status": "blocked",
|
||||
},
|
||||
)
|
||||
@@ -2163,7 +2225,7 @@ def test_user_agent_returns_draft_limit_message_when_save_is_blocked() -> None:
|
||||
|
||||
assert (
|
||||
response.answer
|
||||
== "你当前已保存 3 个草稿,请先完成已保存的草稿,才能再次新建草稿。"
|
||||
== "您当前已保存 3 个草稿,请先完成已保存的草稿,才能再次新建草稿。"
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user