test_tool_description_boundaries.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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_goods_info import QueryGoodsInfoTool
  26. from tools.trial_goods_tax import TrialGoodsTaxTool
  27. from tools.query_receive_volume_list import QueryReceiveVolumeListTool
  28. from tools.list_receive_volume_filter_options import (
  29. ListReceiveVolumeFilterOptionsTool,
  30. )
  31. from tools.query_container_timeliness_list import QueryContainerTimelinessListTool
  32. from tools.query_freightower_track import QueryFreightowerTrackTool
  33. from tools.export_container_timeliness_report import (
  34. ExportContainerTimelinessReportTool,
  35. )
  36. from tools.query_headhaul_document_list import QueryHeadhaulDocumentListTool
  37. from tools.list_headhaul_document_filter_options import (
  38. ListHeadhaulDocumentFilterOptionsTool,
  39. )
  40. from tools.prepare_headhaul_document_upload import (
  41. PrepareHeadhaulDocumentUploadTool,
  42. )
  43. from tools.save_headhaul_document import SaveHeadhaulDocumentTool
  44. from tools.delete_headhaul_document import DeleteHeadhaulDocumentTool
  45. from tools.query_track import QueryTrackTool
  46. class ToolDescriptionBoundaryTest(unittest.TestCase):
  47. def test_every_existing_tool_states_use_and_prohibition_boundaries(self):
  48. tools = (
  49. QueryOrderTool(),
  50. QueryOrderExactTool(),
  51. QueryTrackTool(),
  52. QueryCustomsDeclarationFilesTool(),
  53. QueryOutboundListTool(),
  54. QueryOutboundDetailTool(),
  55. ListOrderFilterOptionsTool(),
  56. ListPendingOutboundExportFilterOptionsTool(),
  57. ExportPendingOutboundOrdersTool(),
  58. ExportOutOfProvincePortDataTool(),
  59. ExportPalletDataTool(),
  60. QueryDestinationTrailerListTool(),
  61. ListDestinationTrailerFilterOptionsTool(),
  62. QueryOrderAbnormalListTool(),
  63. ListOrderAbnormalFilterOptionsTool(),
  64. QueryReceiveVolumeListTool(),
  65. QueryGoodsInfoTool(),
  66. TrialGoodsTaxTool(),
  67. ListReceiveVolumeFilterOptionsTool(),
  68. QueryContainerTimelinessListTool(),
  69. ExportContainerTimelinessReportTool(),
  70. QueryHeadhaulDocumentListTool(),
  71. ListHeadhaulDocumentFilterOptionsTool(),
  72. PrepareHeadhaulDocumentUploadTool(),
  73. SaveHeadhaulDocumentTool(),
  74. DeleteHeadhaulDocumentTool(),
  75. QueryFreightowerTrackTool(),
  76. )
  77. for tool in tools:
  78. with self.subTest(tool=tool.name):
  79. description = tool.metadata()['description']
  80. self.assertIn('使用场景:', description)
  81. self.assertIn('禁止使用:', description)
  82. def test_number_tools_require_clarification_and_forbid_trial_queries(self):
  83. tools = (
  84. QueryOrderTool(),
  85. QueryOrderExactTool(),
  86. QueryTrackTool(),
  87. QueryCustomsDeclarationFilesTool(),
  88. QueryOutboundListTool(),
  89. QueryOutboundDetailTool(),
  90. ExportOutOfProvincePortDataTool(),
  91. ExportPalletDataTool(),
  92. QueryDestinationTrailerListTool(),
  93. QueryOrderAbnormalListTool(),
  94. QueryContainerTimelinessListTool(),
  95. ExportContainerTimelinessReportTool(),
  96. QueryHeadhaulDocumentListTool(),
  97. TrialGoodsTaxTool(),
  98. QueryFreightowerTrackTool(),
  99. )
  100. for tool in tools:
  101. with self.subTest(tool=tool.name):
  102. description = tool.metadata()['description']
  103. self.assertIn('号码类型不明确时必须先询问用户', description)
  104. self.assertIn('不得根据号码格式猜测', description)
  105. self.assertIn('不得跨字段或跨工具试查', description)
  106. def test_result_intent_distinguishes_adjacent_tools(self):
  107. expected = {
  108. QueryOrderTool(): ('旧版跨字段通用搜索', 'query_order_exact', '订单列表'),
  109. QueryOrderExactTool(): ('订单列表', 'query_order_detail', '排舱列表'),
  110. QueryOrderDetailTool(): ('单个订单的详情', '逐个调用', 'query_order_exact', '订单列表'),
  111. QueryTrackTool(): ('物流轨迹', '订单资料', '报关资料文件'),
  112. QueryCustomsDeclarationFilesTool(): ('报关资料文件', '完整排舱详情', '文件链接'),
  113. QueryOutboundListTool(): ('排舱列表', '40个字段', '排舱详情'),
  114. QueryOutboundDetailTool(): ('排舱详情', '11项汇总', '38项订单明细'),
  115. ListOrderFilterOptionsTool(): ('query_order_exact', '授权筛选值', '业务数据'),
  116. ListPendingOutboundExportFilterOptionsTool(): (
  117. 'export_pending_outbound_orders', '授权筛选值', 'query_outbound_list',
  118. ),
  119. ExportPendingOutboundOrdersTool(): ('明确要求导出', '未排舱订单', '查看或查询'),
  120. ExportOutOfProvincePortDataTool(): ('明确要求导出', '省外进港资料', '普通排舱查询'),
  121. ExportPalletDataTool(): ('明确要求导出', '打托数据', 'query_export_task'),
  122. QueryDestinationTrailerListTool(): (
  123. '海外提柜', 'query_outbound_list', '六个类型',
  124. ),
  125. ListDestinationTrailerFilterOptionsTool(): (
  126. 'query_destination_trailer_list', '禁止猜测', '排舱列表',
  127. ),
  128. QueryOrderAbnormalListTool(): (
  129. '头程问题件', 'admin/Order/abnormal', 'query_order',
  130. ),
  131. ListOrderAbnormalFilterOptionsTool(): (
  132. 'query_order_abnormal_list', '禁止猜测', '作废审核',
  133. ),
  134. QueryReceiveVolumeListTool(): (
  135. '收货量', 'admin/Report/receiveForm', 'query_order',
  136. ),
  137. ListReceiveVolumeFilterOptionsTool(): (
  138. 'query_receive_volume_list', '禁止猜测', '导出',
  139. ),
  140. QueryContainerTimelinessListTool(): (
  141. '柜子时效', 'admin/Report/outboundReport', 'query_outbound_list',
  142. ),
  143. ExportContainerTimelinessReportTool(): (
  144. '明确要求导出', '柜子时效', 'query_export_task',
  145. ),
  146. QueryHeadhaulDocumentListTool(): (
  147. '头程文档', 'admin/document/index', 'query_customs_declaration_files',
  148. ),
  149. ListHeadhaulDocumentFilterOptionsTool(): (
  150. 'query_headhaul_document_list', '禁止猜测', '报关资料',
  151. ),
  152. PrepareHeadhaulDocumentUploadTool(): (
  153. '对话窗口', '选文件框', '工具参数',
  154. ),
  155. SaveHeadhaulDocumentTool(): (
  156. 'ticket_ref', '外链', 'OSS路径',
  157. ),
  158. DeleteHeadhaulDocumentTool(): (
  159. 'document_ref', '盲删', '批量删除',
  160. ),
  161. QueryFreightowerTrackTool(): (
  162. '飞驼', 'query_track', '提单号',
  163. ),
  164. }
  165. for tool, phrases in expected.items():
  166. with self.subTest(tool=tool.name):
  167. description = tool.metadata()['description']
  168. for phrase in phrases:
  169. self.assertIn(phrase, description)
  170. def test_outbound_number_fields_require_explicit_business_types(self):
  171. properties = QueryOutboundListTool().metadata()['input_schema']['properties']
  172. for field, label in (
  173. ('outbound_numbers', '排舱单号'),
  174. ('order_numbers', '订单号'),
  175. ('container_codes', '柜号'),
  176. ('so_numbers', 'SO号'),
  177. ('bl_numbers', '提单号'),
  178. ):
  179. with self.subTest(field=field):
  180. description = properties[field]['description']
  181. self.assertIn(label, description)
  182. self.assertIn('仅当用户明确', description)
  183. self.assertIn('不得放入其他类型号码', description)
  184. def test_export_tools_describe_async_follow_up_without_long_wait(self):
  185. for tool in (
  186. ExportPendingOutboundOrdersTool(),
  187. ExportOutOfProvincePortDataTool(),
  188. ExportPalletDataTool(),
  189. ExportContainerTimelinessReportTool(),
  190. ):
  191. with self.subTest(tool=tool.name):
  192. description = tool.metadata()['description']
  193. self.assertIn('异步导出任务', description)
  194. self.assertIn('query_export_task', description)
  195. self.assertIn('不会在本次调用中等待文件生成', description)
  196. if __name__ == '__main__':
  197. unittest.main()