agent_model_acceptance.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import os
  2. from uuid import UUID
  3. from sqlalchemy import func, select
  4. from test_after_sales import scenario # noqa: F401
  5. from zhifu.modules.after_sales.models import Approval, Ticket
  6. from zhifu.modules.agent_runtime.config import AgentSettings
  7. from zhifu.modules.agent_runtime.models import AgentRun, ModelAttempt
  8. from zhifu.modules.agent_runtime.worker import execute_one
  9. from zhifu.modules.integrations.models import ExternalOperation
  10. async def test_real_model_queries_order_and_creates_proposal(scenario): # noqa: F811
  11. settings = AgentSettings()
  12. assert settings.model_name and settings.model_url, "需要配置实际模型名称和地址"
  13. assert os.environ.get(settings.credential_env), "需要配置实际模型凭据"
  14. body = {
  15. "store_id": str(scenario["store"]),
  16. "message": (
  17. f"请查询订单 {scenario['order_id']},商品 keyboard-1 的一个键盘按键失灵。"
  18. "请为我创建数量为 1 的换货方案,创建后告诉我真实方案标识和下一步操作。"
  19. ),
  20. }
  21. response = await scenario["call"](
  22. "POST",
  23. "/openapi/v1/agent/runs",
  24. payload=body,
  25. key="model-acceptance",
  26. )
  27. assert response.status_code == 202, response.text
  28. run_id = UUID(response.json()["run_id"])
  29. repeated = await scenario["call"](
  30. "POST", "/openapi/v1/agent/runs", payload=body, key="model-acceptance"
  31. )
  32. assert repeated.json()["run_id"] == str(run_id)
  33. conflict = await scenario["call"](
  34. "POST",
  35. "/openapi/v1/agent/runs",
  36. payload={**body, "message": "其他问题"},
  37. key="model-acceptance",
  38. )
  39. assert conflict.status_code == 409
  40. app = scenario["app"]
  41. assert await execute_one(app.state.sessions, app.state.state, settings)
  42. response = await scenario["call"]("GET", f"/openapi/v1/agent/runs/{run_id}")
  43. assert response.json()["status"] == "COMPLETED", response.text
  44. async with app.state.sessions() as session:
  45. run = await session.get(AgentRun, run_id.bytes)
  46. calls = {
  47. call["name"]
  48. for message in run.messages
  49. for call in message["data"].get("tool_calls", [])
  50. }
  51. assert {"get_order", "create_exchange_proposal"} <= calls
  52. attempts = (
  53. await session.scalars(select(ModelAttempt).where(ModelAttempt.run_id == run_id.bytes))
  54. ).all()
  55. assert attempts and all(attempt.status == "RECEIVED" for attempt in attempts)
  56. assert all(attempt.usage is not None for attempt in attempts)
  57. tickets = (
  58. await session.scalars(
  59. select(Ticket).where(Ticket.tenant_id == scenario["tenant"].bytes)
  60. )
  61. ).all()
  62. assert len(tickets) == 1 and tickets[0].status == "DRAFT"
  63. for model in (Approval, ExternalOperation):
  64. count = await session.scalar(
  65. select(func.count())
  66. .select_from(model)
  67. .where(model.tenant_id == scenario["tenant"].bytes)
  68. )
  69. assert count == 0
  70. print(
  71. {
  72. "model": settings.model_name,
  73. "model_calls": len(attempts),
  74. "total_tokens": sum(attempt.usage["total_tokens"] for attempt in attempts),
  75. "ticket_status": tickets[0].status,
  76. }
  77. )