feat(server): 新增编排器服务,实现服务间流程编排和任务调度功能
This commit is contained in:
@@ -657,8 +657,8 @@ class OrchestratorService:
|
|||||||
|
|
||||||
if ontology.scenario == "expense":
|
if ontology.scenario == "expense":
|
||||||
tool_type = AgentToolType.DATABASE.value
|
tool_type = AgentToolType.DATABASE.value
|
||||||
tool_name = "database.expense_claims.upsert_draft"
|
tool_name = "database.expense_claims.save_or_submit"
|
||||||
executor = lambda: self.expense_claim_service.upsert_draft_from_ontology(
|
executor = lambda: self.expense_claim_service.save_or_submit_from_ontology(
|
||||||
run_id=run_id,
|
run_id=run_id,
|
||||||
user_id=payload.user_id,
|
user_id=payload.user_id,
|
||||||
message=payload.message or "",
|
message=payload.message or "",
|
||||||
|
|||||||
@@ -629,6 +629,65 @@ def test_orchestrator_user_agent_draft_returns_structured_payload() -> None:
|
|||||||
assert claim.items
|
assert claim.items
|
||||||
|
|
||||||
|
|
||||||
|
def test_orchestrator_expense_next_step_submits_claim_to_approval() -> None:
|
||||||
|
client, session_factory = build_client()
|
||||||
|
user_id = "zhangsan@example.com"
|
||||||
|
|
||||||
|
with session_factory() as db:
|
||||||
|
db.add(
|
||||||
|
Employee(
|
||||||
|
employee_no="E3001",
|
||||||
|
name="张三",
|
||||||
|
email=user_id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
"/api/v1/orchestrator/run",
|
||||||
|
json={
|
||||||
|
"source": "user_message",
|
||||||
|
"user_id": user_id,
|
||||||
|
"message": "帮我报销昨天去上海出差的交通费680元",
|
||||||
|
"context_json": {
|
||||||
|
"role_codes": ["employee"],
|
||||||
|
"name": "张三",
|
||||||
|
"department_name": "销售部",
|
||||||
|
"attachment_names": ["didi-trip.png"],
|
||||||
|
"attachment_count": 1,
|
||||||
|
"review_action": "next_step",
|
||||||
|
"review_form_values": {
|
||||||
|
"reporter_name": "张三",
|
||||||
|
"expense_type": "交通费",
|
||||||
|
"amount": "680",
|
||||||
|
"occurred_date": "2026-05-13",
|
||||||
|
"location": "上海",
|
||||||
|
"reason": "上海客户拜访交通"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
payload = response.json()
|
||||||
|
assert payload["status"] == "succeeded"
|
||||||
|
assert payload["result"]["draft_payload"]["claim_no"].startswith("EXP-")
|
||||||
|
assert payload["result"]["draft_payload"]["status"] == "submitted"
|
||||||
|
assert payload["result"]["draft_payload"]["approval_stage"] == "AI验审"
|
||||||
|
assert "已提交审批" in payload["result"]["answer"]
|
||||||
|
|
||||||
|
with session_factory() as db:
|
||||||
|
claim = db.scalar(
|
||||||
|
select(ExpenseClaim).where(
|
||||||
|
ExpenseClaim.id == payload["result"]["draft_payload"]["claim_id"]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert claim is not None
|
||||||
|
assert claim.status == "submitted"
|
||||||
|
assert claim.approval_stage == "AI验审"
|
||||||
|
assert claim.submitted_at is not None
|
||||||
|
|
||||||
|
|
||||||
def test_orchestrator_blocks_fourth_expense_draft_for_same_user() -> None:
|
def test_orchestrator_blocks_fourth_expense_draft_for_same_user() -> None:
|
||||||
client, session_factory = build_client()
|
client, session_factory = build_client()
|
||||||
user_id = "zhangsan@example.com"
|
user_id = "zhangsan@example.com"
|
||||||
|
|||||||
Reference in New Issue
Block a user