query_outbound_detail.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. class QueryOutboundDetailTool:
  2. name = 'query_outbound_detail'
  3. route_path = '/mcp/tools/queryOutboundDetail'
  4. def __init__(self, api_client=None):
  5. self.api_client = api_client
  6. def metadata(self):
  7. return {
  8. 'name': self.name,
  9. 'description': (
  10. '使用场景:用户明确要查看一张排舱单的排舱详情,并明确提供排舱单号时'
  11. '使用。返回第一层11项汇总和第二层34项订单明细,包括明细表中的报关资料。'
  12. '只接受排舱单号,不接受订单号、柜号、SO号、提单号或数据库ID。用户明确'
  13. '要看排舱详情但只提供订单号时,应先用query_outbound_list按订单号定位;'
  14. '多条命中必须让用户选择。号码类型不明确时必须先询问用户。'
  15. '禁止使用:用户要看排舱列表、订单资料、物流轨迹或仅查看报关资料文件链接'
  16. '时不得使用本工具。不得根据号码格式猜测,不得跨字段或跨工具试查,'
  17. '查询无结果后不得把同一号码改作其他类型重试。'
  18. '公司、员工和权限范围由当前设备会话确定。参数名仅用于工具调用;'
  19. '向用户回答时只能展示中文业务名称,不得展示内部参数名。'
  20. ),
  21. 'input_schema': {
  22. 'type': 'object',
  23. 'properties': {
  24. 'outbound_number': {
  25. 'type': 'string', 'minLength': 1, 'maxLength': 100,
  26. 'description': '排舱单号,不是订单号、柜号、SO号或数据库ID。',
  27. },
  28. 'page': {
  29. 'type': 'integer', 'minimum': 1, 'maximum': 100,
  30. 'default': 1,
  31. },
  32. 'limit': {
  33. 'type': 'integer', 'minimum': 1, 'maximum': 20,
  34. 'default': 10,
  35. },
  36. },
  37. 'required': ['outbound_number'],
  38. 'additionalProperties': False,
  39. },
  40. }
  41. def call(
  42. self,
  43. outbound_number=None,
  44. page=1,
  45. limit=10,
  46. request_id='rq_query_outbound_detail',
  47. ):
  48. if self.api_client is None:
  49. raise RuntimeError('api client is required for query_outbound_detail')
  50. if not isinstance(outbound_number, str):
  51. raise ValueError('outbound_number is required')
  52. outbound_number = outbound_number.strip()
  53. if not outbound_number or len(outbound_number) > 100:
  54. raise ValueError('outbound_number is required')
  55. page = self._bounded_integer(page, 'page', 100)
  56. limit = self._bounded_integer(limit, 'limit', 20)
  57. return self.api_client.call_tool(
  58. self.name,
  59. self.route_path,
  60. {
  61. 'outbound_number': outbound_number,
  62. 'page': page,
  63. 'limit': limit,
  64. },
  65. request_id,
  66. )
  67. @staticmethod
  68. def _bounded_integer(value, field, maximum):
  69. if isinstance(value, bool):
  70. raise ValueError('{0} is invalid'.format(field))
  71. try:
  72. value = int(value)
  73. except (TypeError, ValueError):
  74. raise ValueError('{0} is invalid'.format(field))
  75. if value < 1 or value > maximum:
  76. raise ValueError('{0} is invalid'.format(field))
  77. return value