toolLabel.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package acp
  2. import "regexp"
  3. // DefaultToolLabel 未命中任何规则时的兜底简述
  4. const DefaultToolLabel = "调用工具"
  5. // mcpIdentRe 判断 title 是否为 MCP 工具标识名(service_/data_/storage_/plane_/util_ 前缀)。
  6. // 仅在标识名形态下才走「动作 + 对象」组合,避免误伤内置工具的自然语言 title。
  7. var mcpIdentRe = regexp.MustCompile(`(?i)(^|[^a-z])(service|data|storage|plane|util)_[a-z]`)
  8. // domainNoiseRe 域名中会误触发动作识别的噪声片段(其中的 update 属于对象名而非动作)。
  9. // 在动作识别前先剔除,避免 auto_update / update_log 等被误判为“更新”动作。
  10. var domainNoiseRe = regexp.MustCompile(`(?i)auto_update|system_update|ahub_update|update_log`)
  11. // objectRule 对象词识别规则(title 片段 → 对象中文名)
  12. type objectRule struct {
  13. re *regexp.Regexp
  14. noun string
  15. }
  16. // objectRules 顺序即优先级,更具体的对象必须排在更宽泛的之前。
  17. var objectRules = []objectRule{
  18. // —— Plane 项目管理相关对象 ——
  19. {regexp.MustCompile(`(?i)fault_record`), "故障工单"},
  20. {regexp.MustCompile(`(?i)intake_issue`), "收件箱工作项"},
  21. {regexp.MustCompile(`(?i)sub_issue`), "子工作项"},
  22. {regexp.MustCompile(`(?i)issue_relation|_relation`), "工作项关联"},
  23. {regexp.MustCompile(`(?i)issue_link`), "工作项链接"},
  24. {regexp.MustCompile(`(?i)work_item|_issues?(_|$)|_issue(_|$)|issue`), "工作项"},
  25. {regexp.MustCompile(`(?i)cycle`), "周期"},
  26. {regexp.MustCompile(`(?i)module`), "模块"},
  27. {regexp.MustCompile(`(?i)page`), "页面"},
  28. {regexp.MustCompile(`(?i)workspace_member`), "工作空间成员"},
  29. {regexp.MustCompile(`(?i)project_member`), "项目成员"},
  30. {regexp.MustCompile(`(?i)project_asset`), "项目资源"},
  31. {regexp.MustCompile(`(?i)workspace`), "工作空间"},
  32. {regexp.MustCompile(`(?i)project`), "项目"},
  33. {regexp.MustCompile(`(?i)label`), "标签"},
  34. {regexp.MustCompile(`(?i)state`), "状态"},
  35. {regexp.MustCompile(`(?i)comment`), "评论"},
  36. {regexp.MustCompile(`(?i)sticky|stickies`), "便签"},
  37. {regexp.MustCompile(`(?i)assets?|entity`), "资源"},
  38. // —— 站点 / 监控 / 数据相关对象 ——
  39. {regexp.MustCompile(`(?i)alarm_snapshot`), "告警快照"},
  40. {regexp.MustCompile(`(?i)alarm_statistic`), "告警统计"},
  41. {regexp.MustCompile(`(?i)event_alarm`), "事件告警"},
  42. {regexp.MustCompile(`(?i)alarm`), "告警"},
  43. {regexp.MustCompile(`(?i)shutdown`), "停机"},
  44. {regexp.MustCompile(`(?i)power_flow`), "功率流"},
  45. {regexp.MustCompile(`(?i)mode_info`), "运行模式"},
  46. {regexp.MustCompile(`(?i)base_info`), "基础信息"},
  47. {regexp.MustCompile(`(?i)tou_template`), "电价模板"},
  48. {regexp.MustCompile(`(?i)apower_version`), "APower版本"},
  49. {regexp.MustCompile(`(?i)auto_update|_package|升级包`), "升级包"},
  50. {regexp.MustCompile(`(?i)batch_download`), "批量下载"},
  51. {regexp.MustCompile(`(?i)background_task`), "后台任务"},
  52. {regexp.MustCompile(`(?i)site_analysis`), "站点分析"},
  53. {regexp.MustCompile(`(?i)site_monitor`), "站点监控"},
  54. {regexp.MustCompile(`(?i)_tag|tags_`), "站点标签"},
  55. {regexp.MustCompile(`(?i)site`), "站点"},
  56. {regexp.MustCompile(`(?i)data_pool`), "数据池"},
  57. {regexp.MustCompile(`(?i)_card|_sim|sim_`), "SIM卡"},
  58. {regexp.MustCompile(`(?i)dashboard`), "看板"},
  59. {regexp.MustCompile(`(?i)feedback`), "反馈"},
  60. {regexp.MustCompile(`(?i)monitor`), "监控"},
  61. {regexp.MustCompile(`(?i)snapshot`), "快照数据"},
  62. {regexp.MustCompile(`(?i)system_update_log|ahub_update_log|update_log`), "升级日志"},
  63. {regexp.MustCompile(`(?i)ems_log|mqtt_log|_log(_|$)`), "日志"},
  64. {regexp.MustCompile(`(?i)pid_info|vid_info|emspara`), "EMS参数"},
  65. // —— 数据库 / 存储 ——
  66. {regexp.MustCompile(`(?i)mongo`), "MongoDB"},
  67. {regexp.MustCompile(`(?i)redis`), "Redis缓存"},
  68. {regexp.MustCompile(`(?i)pgsql`), "PostgreSQL"},
  69. {regexp.MustCompile(`(?i)file|minio|object`), "文件"},
  70. }
  71. // actionRule 动作词识别规则(title 片段 → 动词 + 后缀)
  72. type actionRule struct {
  73. re *regexp.Regexp
  74. verb string
  75. suffix string
  76. }
  77. // actionRules 顺序即优先级。变更类动作先于查询类;unarchive 先于 archive;list 先于 get。
  78. var actionRules = []actionRule{
  79. {regexp.MustCompile(`(?i)unarchive`), "取消归档", ""},
  80. {regexp.MustCompile(`(?i)archive`), "归档", ""},
  81. {regexp.MustCompile(`(?i)create`), "创建", ""},
  82. {regexp.MustCompile(`(?i)update|mark`), "更新", ""},
  83. {regexp.MustCompile(`(?i)delete`), "删除", ""},
  84. {regexp.MustCompile(`(?i)remove`), "移除", ""},
  85. {regexp.MustCompile(`(?i)accept`), "受理", ""},
  86. {regexp.MustCompile(`(?i)reject`), "驳回", ""},
  87. {regexp.MustCompile(`(?i)add`), "添加", ""},
  88. {regexp.MustCompile(`(?i)bind`), "绑定", ""},
  89. {regexp.MustCompile(`(?i)trigger`), "触发", ""},
  90. {regexp.MustCompile(`(?i)upload`), "上传", ""},
  91. {regexp.MustCompile(`(?i)write`), "写入", ""},
  92. {regexp.MustCompile(`(?i)read`), "读取", ""},
  93. {regexp.MustCompile(`(?i)search`), "搜索", ""},
  94. {regexp.MustCompile(`(?i)_list(_|$)|list_|_tree|name_list`), "查询", "列表"},
  95. // 查询类兜底动词(get/detail/info/find/query/count/exists 等)
  96. {regexp.MustCompile(`(?i)get|detail|info|find|query|count|exists|options|config|summary|activit`), "查询", ""},
  97. }
  98. // fallbackRules 非 MCP 标识名(内置工具 / 中文描述 / 通用关键词)的兜底映射表。
  99. type toolLabelRule struct {
  100. re *regexp.Regexp
  101. label string
  102. }
  103. var fallbackRules = []toolLabelRule{
  104. {regexp.MustCompile(`(?i)web_search|联网搜索`), "联网搜索"},
  105. {regexp.MustCompile(`(?i)web_fetch|fetch|抓取|网页`), "抓取网页"},
  106. {regexp.MustCompile(`(?i)knowledge|知识库|检索`), "知识库检索"},
  107. {regexp.MustCompile(`(?i)subagent|子任务`), "子任务处理"},
  108. {regexp.MustCompile(`(?i)todo|任务清单`), "任务清单"},
  109. {regexp.MustCompile(`(?i)introspect`), "功能查询"},
  110. {regexp.MustCompile(`(?i)\bcode\b|代码`), "代码分析"},
  111. {regexp.MustCompile(`(?i)grep|搜索|查找`), "搜索内容"},
  112. {regexp.MustCompile(`(?i)glob|查找文件`), "查找文件"},
  113. {regexp.MustCompile(`(?i)read|cat|查看|读取`), "读取文件"},
  114. {regexp.MustCompile(`(?i)write|create|edit|写入|修改`), "写入文件"},
  115. {regexp.MustCompile(`(?i)util_|parse_sn`), "解析序列号"},
  116. {regexp.MustCompile(`(?i)execut|bash|shell|command|执行|运行`), "执行命令"},
  117. }
  118. // DescribeTool 根据工具调用 title 返回详细描述(动作 + 对象)。
  119. //
  120. // MCP 标识名形态:组合「动作 + 对象」,如 create_issue -> “创建工作项”,
  121. // list_work_items -> “查询工作项列表”。
  122. // 其他形态:回退到关键词兜底表;无命中返回 DefaultToolLabel。
  123. func DescribeTool(title string) string {
  124. if title == "" {
  125. return DefaultToolLabel
  126. }
  127. // MCP 标识名 → 动作 + 对象 组合
  128. if mcpIdentRe.MatchString(title) {
  129. obj := ""
  130. for _, r := range objectRules {
  131. if r.re.MatchString(title) {
  132. obj = r.noun
  133. break
  134. }
  135. }
  136. if obj != "" {
  137. // 默认动作为“查询”(大多数无动词的工具是读取类)
  138. verb, suffix := "查询", ""
  139. // 剔除域名噪声后再识别动作,避免 auto_update / update_log 误判为“更新”
  140. actionSrc := domainNoiseRe.ReplaceAllString(title, "_")
  141. for _, a := range actionRules {
  142. if a.re.MatchString(actionSrc) {
  143. verb, suffix = a.verb, a.suffix
  144. break
  145. }
  146. }
  147. return verb + obj + suffix
  148. }
  149. }
  150. // 回退:内置工具 / 中文描述 / 通用关键词
  151. for _, r := range fallbackRules {
  152. if r.re.MatchString(title) {
  153. return r.label
  154. }
  155. }
  156. return DefaultToolLabel
  157. }
  158. // NormalizeStatus 将 ACP / 各来源的工具状态归一化为前端使用的三态:
  159. // running / completed / error。
  160. //
  161. // pending, in_progress, running -> running
  162. // completed -> completed
  163. // failed, error -> error
  164. // 其他(未知) -> running(先按运行中处理,避免误判为错误)
  165. func NormalizeStatus(raw string) string {
  166. switch raw {
  167. case "pending", "in_progress", "running":
  168. return "running"
  169. case "completed":
  170. return "completed"
  171. case "failed", "error":
  172. return "error"
  173. default:
  174. return "running"
  175. }
  176. }