feat: 重构报销单AI预审流程并添加平台风险规则引擎
- 将AI验审改为AI预审,高风险不再拦截而是随单流转给审批人复核 - 新增平台风险规则评估引擎,支持事由过短、票据异常、重复发票等多种评估器 - 用户上下文增加部门信息(department_name),认证流程同步关联组织架构 - 规则scenario_json改为中文标签(差旅/费用科目),统一场景分类 - 新增orchestrator审核流程测试用例 - 前端更新审计视图、差旅报销等相关页面
This commit is contained in:
@@ -173,9 +173,11 @@ class OrchestratorService:
|
||||
task_asset=task_asset,
|
||||
)
|
||||
selected_capability_codes = self._flatten_capability_codes(capabilities)
|
||||
requires_confirmation = (
|
||||
ontology.permission.level == AgentPermissionLevel.APPROVAL_REQUIRED.value
|
||||
)
|
||||
is_expense_review_action = self._is_expense_review_action(context_json)
|
||||
requires_confirmation = (
|
||||
ontology.permission.level == AgentPermissionLevel.APPROVAL_REQUIRED.value
|
||||
and not is_expense_review_action
|
||||
)
|
||||
|
||||
route_json = {
|
||||
"orchestrated_by": AgentName.ORCHESTRATOR.value,
|
||||
@@ -526,7 +528,11 @@ class OrchestratorService:
|
||||
failed_tool_count=1 if degraded else 0,
|
||||
)
|
||||
|
||||
next_step = self._resolve_next_step(ontology, payload.source)
|
||||
next_step = self._resolve_next_step(
|
||||
ontology,
|
||||
payload.source,
|
||||
context_json=context_json,
|
||||
)
|
||||
if next_step == "query_database":
|
||||
tool_payload, degraded = self._invoke_tool(
|
||||
run_id=run_id,
|
||||
@@ -662,9 +668,9 @@ class OrchestratorService:
|
||||
"degraded": True,
|
||||
}
|
||||
|
||||
if ontology.scenario == "expense":
|
||||
tool_type = AgentToolType.DATABASE.value
|
||||
tool_name = "database.expense_claims.save_or_submit"
|
||||
if ontology.scenario == "expense" or self._is_expense_review_action(context_json):
|
||||
tool_type = AgentToolType.DATABASE.value
|
||||
tool_name = "database.expense_claims.save_or_submit"
|
||||
executor = lambda: self.expense_claim_service.save_or_submit_from_ontology(
|
||||
run_id=run_id,
|
||||
user_id=payload.user_id,
|
||||
@@ -781,10 +787,17 @@ class OrchestratorService:
|
||||
failed_tool_count=failed_tool_count,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _resolve_next_step(ontology: OntologyParseResult, source: str) -> str:
|
||||
if ontology.clarification_required:
|
||||
return "ask_clarification"
|
||||
@staticmethod
|
||||
def _resolve_next_step(
|
||||
ontology: OntologyParseResult,
|
||||
source: str,
|
||||
*,
|
||||
context_json: dict[str, Any] | None = None,
|
||||
) -> str:
|
||||
if OrchestratorService._is_expense_review_action(context_json or {}):
|
||||
return "create_draft"
|
||||
if ontology.clarification_required:
|
||||
return "ask_clarification"
|
||||
if ontology.intent == "draft":
|
||||
return "create_draft"
|
||||
if ontology.scenario == "knowledge" or ontology.intent == "explain":
|
||||
@@ -793,7 +806,18 @@ class OrchestratorService:
|
||||
return "run_rule"
|
||||
if ontology.intent in {"query", "compare"}:
|
||||
return "query_database"
|
||||
return "create_draft"
|
||||
return "create_draft"
|
||||
|
||||
@staticmethod
|
||||
def _is_expense_review_action(context_json: dict[str, Any]) -> bool:
|
||||
review_action = str((context_json or {}).get("review_action") or "").strip()
|
||||
return review_action in {
|
||||
"save_draft",
|
||||
"next_step",
|
||||
"edit_review",
|
||||
"link_to_existing_draft",
|
||||
"create_new_claim_from_documents",
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _flatten_capability_codes(
|
||||
|
||||
Reference in New Issue
Block a user