test_tool_description_boundaries.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import unittest
  2. from tools.export_out_of_province_port_data import (
  3. ExportOutOfProvincePortDataTool,
  4. )
  5. from tools.export_pallet_data import ExportPalletDataTool
  6. from tools.export_pending_outbound_orders import ExportPendingOutboundOrdersTool
  7. from tools.list_order_filter_options import ListOrderFilterOptionsTool
  8. from tools.list_pending_outbound_export_filter_options import (
  9. ListPendingOutboundExportFilterOptionsTool,
  10. )
  11. from tools.query_customs_declaration_files import QueryCustomsDeclarationFilesTool
  12. from tools.query_order import QueryOrderTool
  13. from tools.query_order_detail import QueryOrderDetailTool
  14. from tools.query_order_exact import QueryOrderExactTool
  15. from tools.query_outbound_detail import QueryOutboundDetailTool
  16. from tools.query_outbound_list import QueryOutboundListTool
  17. from tools.query_destination_trailer_list import QueryDestinationTrailerListTool
  18. from tools.list_destination_trailer_filter_options import (
  19. ListDestinationTrailerFilterOptionsTool,
  20. )
  21. from tools.query_order_abnormal_list import QueryOrderAbnormalListTool
  22. from tools.list_order_abnormal_filter_options import (
  23. ListOrderAbnormalFilterOptionsTool,
  24. )
  25. from tools.query_track import QueryTrackTool
  26. class ToolDescriptionBoundaryTest(unittest.TestCase):
  27. def test_every_existing_tool_states_use_and_prohibition_boundaries(self):
  28. tools = (
  29. QueryOrderTool(),
  30. QueryOrderExactTool(),
  31. QueryTrackTool(),
  32. QueryCustomsDeclarationFilesTool(),
  33. QueryOutboundListTool(),
  34. QueryOutboundDetailTool(),
  35. ListOrderFilterOptionsTool(),
  36. ListPendingOutboundExportFilterOptionsTool(),
  37. ExportPendingOutboundOrdersTool(),
  38. ExportOutOfProvincePortDataTool(),
  39. ExportPalletDataTool(),
  40. QueryDestinationTrailerListTool(),
  41. ListDestinationTrailerFilterOptionsTool(),
  42. QueryOrderAbnormalListTool(),
  43. ListOrderAbnormalFilterOptionsTool(),
  44. )
  45. for tool in tools:
  46. with self.subTest(tool=tool.name):
  47. description = tool.metadata()['description']
  48. self.assertIn('使用场景:', description)
  49. self.assertIn('禁止使用:', description)
  50. def test_number_tools_require_clarification_and_forbid_trial_queries(self):
  51. tools = (
  52. QueryOrderTool(),
  53. QueryOrderExactTool(),
  54. QueryTrackTool(),
  55. QueryCustomsDeclarationFilesTool(),
  56. QueryOutboundListTool(),
  57. QueryOutboundDetailTool(),
  58. ExportOutOfProvincePortDataTool(),
  59. ExportPalletDataTool(),
  60. QueryDestinationTrailerListTool(),
  61. QueryOrderAbnormalListTool(),
  62. )
  63. for tool in tools:
  64. with self.subTest(tool=tool.name):
  65. description = tool.metadata()['description']
  66. self.assertIn('号码类型不明确时必须先询问用户', description)
  67. self.assertIn('不得根据号码格式猜测', description)
  68. self.assertIn('不得跨字段或跨工具试查', description)
  69. def test_result_intent_distinguishes_adjacent_tools(self):
  70. expected = {
  71. QueryOrderTool(): ('旧版跨字段通用搜索', 'query_order_exact', '订单列表'),
  72. QueryOrderExactTool(): ('订单列表', 'query_order_detail', '排舱列表'),
  73. QueryOrderDetailTool(): ('单个订单的详情', '逐个调用', 'query_order_exact', '订单列表'),
  74. QueryTrackTool(): ('物流轨迹', '订单资料', '报关资料文件'),
  75. QueryCustomsDeclarationFilesTool(): ('报关资料文件', '完整排舱详情', '文件链接'),
  76. QueryOutboundListTool(): ('排舱列表', '40个字段', '排舱详情'),
  77. QueryOutboundDetailTool(): ('排舱详情', '11项汇总', '38项订单明细'),
  78. ListOrderFilterOptionsTool(): ('query_order_exact', '授权筛选值', '业务数据'),
  79. ListPendingOutboundExportFilterOptionsTool(): (
  80. 'export_pending_outbound_orders', '授权筛选值', 'query_outbound_list',
  81. ),
  82. ExportPendingOutboundOrdersTool(): ('明确要求导出', '未排舱订单', '查看或查询'),
  83. ExportOutOfProvincePortDataTool(): ('明确要求导出', '省外进港资料', '普通排舱查询'),
  84. ExportPalletDataTool(): ('明确要求导出', '打托数据', 'query_export_task'),
  85. QueryDestinationTrailerListTool(): (
  86. '海外提柜', 'query_outbound_list', '六个类型',
  87. ),
  88. ListDestinationTrailerFilterOptionsTool(): (
  89. 'query_destination_trailer_list', '禁止猜测', '排舱列表',
  90. ),
  91. QueryOrderAbnormalListTool(): (
  92. '头程问题件', 'admin/Order/abnormal', 'query_order',
  93. ),
  94. ListOrderAbnormalFilterOptionsTool(): (
  95. 'query_order_abnormal_list', '禁止猜测', '作废审核',
  96. ),
  97. }
  98. for tool, phrases in expected.items():
  99. with self.subTest(tool=tool.name):
  100. description = tool.metadata()['description']
  101. for phrase in phrases:
  102. self.assertIn(phrase, description)
  103. def test_outbound_number_fields_require_explicit_business_types(self):
  104. properties = QueryOutboundListTool().metadata()['input_schema']['properties']
  105. for field, label in (
  106. ('outbound_numbers', '排舱单号'),
  107. ('order_numbers', '订单号'),
  108. ('container_codes', '柜号'),
  109. ('so_numbers', 'SO号'),
  110. ('bl_numbers', '提单号'),
  111. ):
  112. with self.subTest(field=field):
  113. description = properties[field]['description']
  114. self.assertIn(label, description)
  115. self.assertIn('仅当用户明确', description)
  116. self.assertIn('不得放入其他类型号码', description)
  117. def test_export_tools_describe_async_follow_up_without_long_wait(self):
  118. for tool in (
  119. ExportPendingOutboundOrdersTool(),
  120. ExportOutOfProvincePortDataTool(),
  121. ExportPalletDataTool(),
  122. ):
  123. with self.subTest(tool=tool.name):
  124. description = tool.metadata()['description']
  125. self.assertIn('异步导出任务', description)
  126. self.assertIn('query_export_task', description)
  127. self.assertIn('不会在本次调用中等待文件生成', description)
  128. if __name__ == '__main__':
  129. unittest.main()