money_budget_model_acceptance.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. from uuid import UUID
  2. import pytest
  3. from sqlalchemy import select
  4. from test_after_sales import scenario # noqa: F401
  5. from test_money_budget import PRICE, approve, budget, setup
  6. from zhifu.modules.agent_runtime.budget_callback import CallAllowance
  7. from zhifu.modules.agent_runtime.config import AgentSettings
  8. from zhifu.modules.agent_runtime.models import AgentRun, ModelAttempt
  9. from zhifu.modules.agent_runtime.worker import execute_one
  10. from zhifu.operations.token_budget import entries
  11. @pytest.mark.parametrize("code", ["MONEY_BUDGET_EXCEEDED", "BILLING_PRICE_MISSING"])
  12. async def test_money_admission_prevents_model_send(scenario, code): # noqa: F811
  13. """使用已配置的真实客户端,预算回调在供应商请求前拒绝;不发送生成请求。"""
  14. await setup(scenario)
  15. await budget(scenario, 0)
  16. if code == "MONEY_BUDGET_EXCEEDED":
  17. await approve(scenario, PRICE)
  18. sessions = scenario["app"].state.sessions
  19. state = scenario["app"].state.state
  20. async for _ in state.scan_iter(match="monitor:worker:agent:*"):
  21. raise RuntimeError("请停止 Agent 工作进程并等待心跳过期")
  22. response = await scenario["call"](
  23. "POST",
  24. "/openapi/v1/agent/runs",
  25. payload={"store_id": str(scenario["store"]), "message": "你好"},
  26. )
  27. assert response.status_code == 202
  28. identifier = UUID(response.json()["run_id"]).bytes
  29. assert await execute_one(
  30. sessions, state, AgentSettings(max_output_tokens=128), allowance=CallAllowance(1)
  31. )
  32. async with sessions() as session:
  33. run = await session.get(AgentRun, identifier)
  34. attempt = await session.scalar(
  35. select(ModelAttempt).where(ModelAttempt.run_id == identifier)
  36. )
  37. assert run.status == "FAILED" and run.error_code == code
  38. assert attempt.status == "NOT_SENT"
  39. assert (await entries(sessions, scenario["tenant"].bytes))["items"] == []