mm_os 3.3.1 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/LICENSE +21 -201
  2. package/README.md +498 -99
  3. package/README_EN.md +505 -0
  4. package/adapter/adapter.js +431 -0
  5. package/adapter/custom_persistence.js +660 -0
  6. package/adapter/mqtt.js +273 -0
  7. package/adapter/socket.js +113 -0
  8. package/adapter/web.js +67 -0
  9. package/adapter/websocket.js +146 -0
  10. package/com/api/com.json +5 -0
  11. package/{core/com → com}/api/config.tpl.json +8 -8
  12. package/com/api/drive.js +708 -0
  13. package/com/api/index.js +198 -0
  14. package/com/api/oauth.js +200 -0
  15. package/com/api/script.tpl.js +32 -0
  16. package/com/cmd/README.md +11 -0
  17. package/com/cmd/com.json +5 -0
  18. package/com/cmd/config.tpl.json +122 -0
  19. package/com/cmd/drive.js +1548 -0
  20. package/com/cmd/index.js +1066 -0
  21. package/com/cmd/msg.json +48 -0
  22. package/com/cmd/nlp.js +525 -0
  23. package/com/cmd/script.tpl.js +32 -0
  24. package/com/db/com.json +5 -0
  25. package/com/db/drive.js +1999 -0
  26. package/com/db/index.js +242 -0
  27. package/{core/com → com}/event/README.md +4 -4
  28. package/com/event/com.json +5 -0
  29. package/{core/com → com}/event/config.tpl.json +18 -18
  30. package/com/event/drive.js +59 -0
  31. package/com/event/index.js +409 -0
  32. package/com/event/script.tpl.js +23 -0
  33. package/com/mqtt/com.json +5 -0
  34. package/{core/com → com}/mqtt/config.tpl.json +3 -5
  35. package/com/mqtt/drive.js +676 -0
  36. package/com/mqtt/index.js +822 -0
  37. package/com/mqtt/mm_mqtt.js +425 -0
  38. package/com/mqtt/script.tpl.js +723 -0
  39. package/com/nav/com.json +5 -0
  40. package/com/nav/config.tpl.json +84 -0
  41. package/com/nav/drive.js +702 -0
  42. package/com/nav/index.js +231 -0
  43. package/{core/com → com}/nav/tpl/admin_pc/page_config.vue +280 -280
  44. package/{core/com → com}/nav/tpl/admin_pc/page_config_form.vue +194 -194
  45. package/com/nav/tpl/admin_pc/page_form.vue +180 -0
  46. package/com/nav/tpl/admin_pc/page_view.vue +124 -0
  47. package/com/nav/tpl/dev_pc/page_default.vue +247 -0
  48. package/com/nav/tpl/dev_pc/page_type.vue +313 -0
  49. package/com/nav/tpl/home_pc/page_default.vue +234 -0
  50. package/com/nav/tpl/home_pc/page_form.vue +137 -0
  51. package/com/nav/tpl/home_pc/page_list.vue +234 -0
  52. package/com/nav/tpl/home_pc/page_nav.vue +221 -0
  53. package/com/nav/tpl/home_pc/page_type.vue +234 -0
  54. package/com/nav/tpl/home_pc/page_view.vue +125 -0
  55. package/com/nav/tpl/home_phone/page_channel.vue +234 -0
  56. package/com/nav/tpl/home_phone/page_default.vue +234 -0
  57. package/com/nav/tpl/home_phone/page_form.vue +137 -0
  58. package/com/nav/tpl/home_phone/page_nav.vue +237 -0
  59. package/com/nav/tpl/home_phone/page_type.vue +234 -0
  60. package/com/nav/tpl/home_phone/page_view.vue +125 -0
  61. package/com/nav/viewmodel.js +446 -0
  62. package/com/param/com.json +5 -0
  63. package/{core/com → com}/param/config.tpl.json +7 -1
  64. package/com/param/drive.js +502 -0
  65. package/com/param/index.js +155 -0
  66. package/com/param/script.tpl.js +12 -0
  67. package/com/pendant/com.json +5 -0
  68. package/{core/com/component → com/pendant}/config.tpl.json +15 -13
  69. package/com/pendant/drive.js +204 -0
  70. package/com/pendant/index.js +441 -0
  71. package/com/pendant/pendant.html +16 -0
  72. package/com/pendant/script.tpl.js +18 -0
  73. package/com/socket/com.json +5 -0
  74. package/com/socket/config.tpl.json +12 -0
  75. package/com/socket/drive.js +651 -0
  76. package/com/socket/index.js +351 -0
  77. package/com/socket/script.tpl.js +41 -0
  78. package/com/sql/com.json +5 -0
  79. package/{core/com → com}/sql/config.tpl.json +13 -9
  80. package/com/sql/drive.js +1259 -0
  81. package/com/sql/index.js +150 -0
  82. package/com/sql/script.tpl.js +47 -0
  83. package/com/static/com.json +5 -0
  84. package/{core/com → com}/static/config.tpl.json +10 -6
  85. package/com/static/drive.js +194 -0
  86. package/com/static/index.js +226 -0
  87. package/com/static/script.tpl.js +28 -0
  88. package/com/task/com.json +5 -0
  89. package/{core/com → com}/task/config.tpl.json +4 -6
  90. package/com/task/drive.js +405 -0
  91. package/com/task/index.js +148 -0
  92. package/com/task/script.tpl.js +37 -0
  93. package/com/template/com.json +5 -0
  94. package/com/template/config.tpl.json +16 -0
  95. package/com/template/drive.js +80 -0
  96. package/com/template/index.js +141 -0
  97. package/com.js +156 -0
  98. package/common/README.md +2 -0
  99. package/common/handler/msg/handler.json +22 -0
  100. package/common/handler/msg/index.js +23 -0
  101. package/common/handler/player/handler.json +22 -0
  102. package/common/handler/player/index.js +287 -0
  103. package/common/handler/user/handler.json +22 -0
  104. package/common/handler/user/index.js +23 -0
  105. package/common/middleware/web_after/index.js +29 -0
  106. package/common/middleware/web_after/middleware.json +9 -0
  107. package/common/middleware/web_base/index.js +113 -0
  108. package/common/middleware/web_base/middleware.json +19 -0
  109. package/common/middleware/web_before/index.js +33 -0
  110. package/common/middleware/web_before/middleware.json +9 -0
  111. package/common/middleware/web_cors/index.js +87 -0
  112. package/common/middleware/web_cors/middleware.json +24 -0
  113. package/common/middleware/web_error/index.js +119 -0
  114. package/common/middleware/web_error/middleware.json +18 -0
  115. package/common/middleware/web_ip/index.js +15 -0
  116. package/common/middleware/web_ip/middleware.json +14 -0
  117. package/common/middleware/web_logger/index.js +156 -0
  118. package/common/middleware/web_logger/middleware.json +14 -0
  119. package/common/middleware/web_main/index.js +24 -0
  120. package/common/middleware/web_main/middleware.json +9 -0
  121. package/common/middleware/web_static/index.js +73 -0
  122. package/common/middleware/web_static/middleware.json +54 -0
  123. package/common/middleware/web_waf/index.js +385 -0
  124. package/common/middleware/web_waf/middleware.json +13 -0
  125. package/common/model/msg/index.js +88 -0
  126. package/common/model/msg/model.json +401 -0
  127. package/common/model/player/index.js +63 -0
  128. package/common/model/player/model.json +185 -0
  129. package/common/model/user/index.js +11 -0
  130. package/common/model/user/model.json +219 -0
  131. package/core/app/config.tpl.json +67 -0
  132. package/core/app/index.js +632 -0
  133. package/core/app/script.tpl.js +52 -0
  134. package/core/channel/index.js +899 -0
  135. package/core/channel/matcher.js +585 -0
  136. package/core/com/config.tpl.json +16 -0
  137. package/core/com/index.js +74 -0
  138. package/core/com/script.tpl.js +5 -0
  139. package/core/component/component.js +42 -0
  140. package/core/component/config.tpl.json +63 -0
  141. package/core/component/index.js +273 -0
  142. package/core/component/script.tpl.js +19 -0
  143. package/core/controller/config.tpl.json +14 -0
  144. package/core/controller/index.js +373 -0
  145. package/core/controller/script.tpl.js +27 -0
  146. package/core/factory/config.tpl.json +14 -0
  147. package/core/factory/entity.js +275 -0
  148. package/core/factory/index.js +241 -0
  149. package/core/factory/script.tpl.js +16 -0
  150. package/core/game/bat/index.js +137 -0
  151. package/core/game/bat/world.js +622 -0
  152. package/core/game/config.tpl.json +16 -0
  153. package/core/game/entity_admin.js +230 -0
  154. package/core/game/index.js +186 -0
  155. package/core/handler/config.tpl.json +22 -0
  156. package/core/handler/index.js +181 -0
  157. package/core/handler/script.tpl.js +23 -0
  158. package/core/logic/config.tpl.json +14 -0
  159. package/core/logic/index.js +59 -0
  160. package/core/logic/script.tpl.js +19 -0
  161. package/core/middleware/config.tpl.json +16 -0
  162. package/core/middleware/index.js +125 -0
  163. package/core/middleware/script.tpl.js +37 -0
  164. package/core/mod/config.tpl.json +22 -0
  165. package/core/mod/index.js +130 -0
  166. package/core/mod/script.tpl.js +34 -0
  167. package/core/model/config.tpl.json +219 -0
  168. package/core/model/index.js +272 -0
  169. package/core/model/model.js +27 -0
  170. package/core/model/script.tpl.js +20 -0
  171. package/core/notifier/config.tpl.json +14 -0
  172. package/core/notifier/index.js +77 -0
  173. package/core/notifier/script.tpl.js +20 -0
  174. package/core/plugin/config.tpl.json +24 -0
  175. package/core/plugin/index.js +232 -0
  176. package/core/plugin/script.tpl.js +51 -0
  177. package/core/pusher/config.tpl.json +14 -0
  178. package/core/pusher/index.js +161 -0
  179. package/core/pusher/script.tpl.js +20 -0
  180. package/core/room/bat/index.js +170 -0
  181. package/core/room/bat/room.js +524 -0
  182. package/core/room/config.tpl.json +20 -0
  183. package/core/room/index.js +249 -0
  184. package/core/room/room.js +61 -0
  185. package/core/scene/config.tpl.json +14 -0
  186. package/core/scene/index.js +466 -0
  187. package/core/scene/loop.js +1255 -0
  188. package/core/scene/map.js +28 -0
  189. package/core/scene/script.tpl.js +22 -0
  190. package/core/sender/config.tpl.json +14 -0
  191. package/core/sender/index.js +79 -0
  192. package/core/sender/script.tpl.js +20 -0
  193. package/core/service/config.tpl.json +14 -0
  194. package/core/service/index.js +100 -0
  195. package/core/service/script.tpl.js +25 -0
  196. package/core/store/config.tpl.json +26 -0
  197. package/core/store/index.js +1755 -0
  198. package/core/store/script.tpl.js +22 -0
  199. package/core/store/sql.js +1464 -0
  200. package/core/system/config.tpl.json +18 -0
  201. package/core/system/index.js +312 -0
  202. package/core/system/script.tpl.js +77 -0
  203. package/core/view/config.tpl.json +14 -0
  204. package/core/view/index.js +91 -0
  205. package/core/view/script.tpl.js +20 -0
  206. package/core/zone/bat/index.js +725 -0
  207. package/core/zone/config.tpl.json +54 -0
  208. package/core/zone/index.js +614 -0
  209. package/core/zone/script.tpl.js +10 -0
  210. package/core/zone/zone_bat.js +136 -0
  211. package/core//345/237/272/347/261/273/346/250/241/345/235/227/346/270/205/345/215/225.md +24 -0
  212. package/index.js +17 -333
  213. package/os.js +57 -0
  214. package/package.json +65 -55
  215. package/server.js +598 -0
  216. package/README.en.md +0 -36
  217. package/conf.json +0 -3
  218. package/core/base/mqtt/index.js +0 -1110
  219. package/core/base/mqtt/lib.js +0 -40
  220. package/core/base/web/index.js +0 -245
  221. package/core/com/api/com.json +0 -4
  222. package/core/com/api/drive.js +0 -668
  223. package/core/com/api/index.js +0 -108
  224. package/core/com/api/oauth.js +0 -158
  225. package/core/com/api/script.js +0 -32
  226. package/core/com/app/README.md +0 -3
  227. package/core/com/app/com.json +0 -4
  228. package/core/com/app/config.tpl.json +0 -16
  229. package/core/com/app/drive.js +0 -309
  230. package/core/com/app/index.js +0 -211
  231. package/core/com/app/script.js +0 -155
  232. package/core/com/cmd/com.json +0 -4
  233. package/core/com/cmd/config.tpl.json +0 -66
  234. package/core/com/cmd/drive.js +0 -513
  235. package/core/com/cmd/index.js +0 -354
  236. package/core/com/cmd/old/5w2h.js +0 -54
  237. package/core/com/cmd/old/drive.js +0 -423
  238. package/core/com/cmd/script.js +0 -11
  239. package/core/com/component/README.md +0 -3
  240. package/core/com/component/com.json +0 -4
  241. package/core/com/component/component.html +0 -16
  242. package/core/com/component/drive.js +0 -197
  243. package/core/com/component/index.js +0 -312
  244. package/core/com/component/script.js +0 -18
  245. package/core/com/db/com.json +0 -4
  246. package/core/com/db/drive.js +0 -1160
  247. package/core/com/db/index.js +0 -176
  248. package/core/com/event/com.json +0 -4
  249. package/core/com/event/drive.js +0 -133
  250. package/core/com/event/index.js +0 -345
  251. package/core/com/event/script.js +0 -26
  252. package/core/com/eventer/com.js +0 -477
  253. package/core/com/eventer/com.json +0 -4
  254. package/core/com/middleware/com.js +0 -154
  255. package/core/com/middleware/com.json +0 -4
  256. package/core/com/middleware/config.tpl.json +0 -8
  257. package/core/com/middleware/script.js +0 -9
  258. package/core/com/mqtt/com.json +0 -4
  259. package/core/com/mqtt/drive.js +0 -600
  260. package/core/com/mqtt/index.js +0 -572
  261. package/core/com/mqtt/mm_mqtt.js +0 -330
  262. package/core/com/mqtt/script.js +0 -604
  263. package/core/com/msg/com.js +0 -296
  264. package/core/com/msg/com.json +0 -4
  265. package/core/com/nav/com.json +0 -4
  266. package/core/com/nav/config.tpl.json +0 -75
  267. package/core/com/nav/drive.js +0 -549
  268. package/core/com/nav/index.js +0 -182
  269. package/core/com/nav/tpl/admin_pc/page_form.vue +0 -180
  270. package/core/com/nav/tpl/admin_pc/page_view.vue +0 -124
  271. package/core/com/nav/tpl/dev_pc/page_default.vue +0 -247
  272. package/core/com/nav/tpl/dev_pc/page_type.vue +0 -313
  273. package/core/com/nav/tpl/home_pc/page_default.vue +0 -234
  274. package/core/com/nav/tpl/home_pc/page_form.vue +0 -137
  275. package/core/com/nav/tpl/home_pc/page_list.vue +0 -234
  276. package/core/com/nav/tpl/home_pc/page_nav.vue +0 -221
  277. package/core/com/nav/tpl/home_pc/page_type.vue +0 -234
  278. package/core/com/nav/tpl/home_pc/page_view.vue +0 -125
  279. package/core/com/nav/tpl/home_phone/page_channel.vue +0 -234
  280. package/core/com/nav/tpl/home_phone/page_default.vue +0 -234
  281. package/core/com/nav/tpl/home_phone/page_form.vue +0 -137
  282. package/core/com/nav/tpl/home_phone/page_nav.vue +0 -237
  283. package/core/com/nav/tpl/home_phone/page_type.vue +0 -234
  284. package/core/com/nav/tpl/home_phone/page_view.vue +0 -125
  285. package/core/com/nav/viewmodel.js +0 -296
  286. package/core/com/param/drive.js +0 -366
  287. package/core/com/param/index.js +0 -80
  288. package/core/com/param/script.js +0 -12
  289. package/core/com/param/test.js +0 -98
  290. package/core/com/plugin/README.md +0 -3
  291. package/core/com/plugin/com.json +0 -4
  292. package/core/com/plugin/config.tpl.json +0 -26
  293. package/core/com/plugin/drive.js +0 -536
  294. package/core/com/plugin/index.js +0 -259
  295. package/core/com/plugin/script.js +0 -213
  296. package/core/com/rpc/com.json +0 -4
  297. package/core/com/rpc/drive.js +0 -160
  298. package/core/com/rpc/index.js +0 -87
  299. package/core/com/rpc/rpc.js +0 -118
  300. package/core/com/socket/com.json +0 -4
  301. package/core/com/socket/config.tpl.json +0 -14
  302. package/core/com/socket/drive.js +0 -403
  303. package/core/com/socket/index.js +0 -62
  304. package/core/com/socket/script.js +0 -42
  305. package/core/com/sql/drive.js +0 -1087
  306. package/core/com/sql/index.js +0 -83
  307. package/core/com/sql/script.js +0 -48
  308. package/core/com/static/com.json +0 -4
  309. package/core/com/static/drive.js +0 -220
  310. package/core/com/static/index.js +0 -149
  311. package/core/com/static/script.js +0 -28
  312. package/core/com/task/com.json +0 -4
  313. package/core/com/task/drive.js +0 -403
  314. package/core/com/task/index.js +0 -110
  315. package/core/com/task/script.js +0 -37
  316. package/core/com/timer/com.js +0 -217
  317. package/core/com/timer/com.json +0 -4
  318. package/core/com/tpl/com.js +0 -19
  319. package/core/com/tpl/com.json +0 -4
  320. package/lib/actions.js +0 -50
  321. package/lib/base.js +0 -361
  322. package/lib/com.js +0 -29
  323. package/lib/ref.js +0 -121
  324. package/middleware/cors/index.js +0 -119
  325. package/middleware/cors/middleware.json +0 -20
  326. package/middleware/csrf/index.js +0 -202
  327. package/middleware/csrf/middleware.json +0 -24
  328. package/middleware/ip_firewall/index.js +0 -476
  329. package/middleware/ip_firewall/middleware.json +0 -109
  330. package/middleware/mqtt_base/index.js +0 -10
  331. package/middleware/mqtt_base/middleware.json +0 -11
  332. package/middleware/security_audit/index.js +0 -543
  333. package/middleware/security_audit/middleware.json +0 -48
  334. package/middleware/waf/index.js +0 -343
  335. package/middleware/waf/middleware.json +0 -10
  336. package/middleware/waf_ddos/index.js +0 -520
  337. package/middleware/waf_ddos/middleware.json +0 -38
  338. package/middleware/waf_xss/index.js +0 -269
  339. package/middleware/waf_xss/middleware.json +0 -18
  340. package/middleware/web_after/index.js +0 -33
  341. package/middleware/web_after/middleware.json +0 -10
  342. package/middleware/web_base/index.js +0 -90
  343. package/middleware/web_base/middleware.json +0 -10
  344. package/middleware/web_before/index.js +0 -27
  345. package/middleware/web_before/middleware.json +0 -10
  346. package/middleware/web_check/index.js +0 -28
  347. package/middleware/web_check/middleware.json +0 -10
  348. package/middleware/web_main/index.js +0 -28
  349. package/middleware/web_main/middleware.json +0 -10
  350. package/middleware/web_proxy/index.js +0 -37
  351. package/middleware/web_proxy/middleware.json +0 -10
  352. package/middleware/web_render/index.js +0 -87
  353. package/middleware/web_render/middleware.json +0 -10
  354. package/middleware/web_socket/index.js +0 -34
  355. package/middleware/web_socket/middleware.json +0 -10
  356. package/middleware/web_static/index.js +0 -115
  357. package/middleware/web_static/middleware.json +0 -10
  358. /package/{core/com → com}/api/README.md +0 -0
  359. /package/{core/com → com}/db/README.md +0 -0
  360. /package/{core/com → com}/mqtt/README.md +0 -0
  361. /package/{core/com → com}/nav/README.md +0 -0
  362. /package/{core/com → com}/nav/tpl/admin_pc/page_channel.vue +0 -0
  363. /package/{core/com → com}/nav/tpl/admin_pc/page_default.vue +0 -0
  364. /package/{core/com → com}/nav/tpl/admin_pc/page_lang.vue +0 -0
  365. /package/{core/com → com}/nav/tpl/admin_pc/page_nav.vue +0 -0
  366. /package/{core/com → com}/nav/tpl/admin_pc/page_table.vue +0 -0
  367. /package/{core/com → com}/nav/tpl/admin_pc/page_type.vue +0 -0
  368. /package/{core/com → com}/nav/tpl/dev_pc/page_channel.vue +0 -0
  369. /package/{core/com → com}/nav/tpl/dev_pc/page_config.vue +0 -0
  370. /package/{core/com → com}/nav/tpl/dev_pc/page_form.vue +0 -0
  371. /package/{core/com → com}/nav/tpl/dev_pc/page_nav.vue +0 -0
  372. /package/{core/com → com}/nav/tpl/dev_pc/page_table.vue +0 -0
  373. /package/{core/com → com}/nav/tpl/home_pc/page_channel.vue +0 -0
  374. /package/{core/com → com}/nav/tpl/home_phone/page_list.vue +0 -0
  375. /package/{core/com → com}/param/README.md +0 -0
  376. /package/{core/com/cmd → com/pendant}/README.md +0 -0
  377. /package/{core/com → com}/socket/README.md +0 -0
  378. /package/{core/com → com}/sql/README.md +0 -0
  379. /package/{core/com → com}/static/README.md +0 -0
  380. /package/{core/com → com}/task/README.md +0 -0
@@ -0,0 +1,1066 @@
1
+ const Manager = require('mm_machine').Manager;
2
+ const Drive = require('./drive');
3
+ const OpenAI = require('openai');
4
+
5
+ /**
6
+ * Cmd指令类
7
+ * @augments {Manager}
8
+ * @class
9
+ */
10
+ class Cmd extends Manager {
11
+ /**
12
+ * 配置参数
13
+ * @type {object}
14
+ */
15
+ static config = {
16
+ // 模块名称
17
+ name: '',
18
+ // 模块标题
19
+ title: 'Cmd指令管理',
20
+ // 文件名
21
+ filename: 'cmd.json',
22
+ // 模板目录
23
+ tpl_dir: __dirname,
24
+ // 自定义目录,加载项目自定义资源
25
+ dir: './app'.fullname(),
26
+ /**
27
+ * 搜索模式 dir按目录搜索 | file按文件名搜索
28
+ * @type {string}
29
+ */
30
+ search_way: 'file',
31
+ // 数据库表名
32
+ table: 'wechat_message',
33
+ // 主键
34
+ key: 'message_id',
35
+ // 缓存前缀
36
+ cache_prefix: 'cmd_',
37
+ // 聊天间隔时长,单位:秒,600秒为10分钟
38
+ interval: 600,
39
+ // 是否启用AI对话, 如果为空则不使用
40
+ ai: 'deepseek',
41
+ // AI API密钥
42
+ api_key: 'sk-0521b7b3e9494a5e844b66ec4787f89d',
43
+ // API端点
44
+ base_url: 'https://api.deepseek.com',
45
+ // 模型名称
46
+ model: 'deepseek-chat',
47
+ // 最大对话轮数
48
+ max_turns: 50,
49
+ // 最大令牌数
50
+ max_tokens: 2048,
51
+ // 温度参数
52
+ temperature: 0.8
53
+ };
54
+
55
+ /**
56
+ * 消息对象
57
+ * @type {object}
58
+ */
59
+ static msg = {
60
+ // 消息ID
61
+ 'message_id': 0,
62
+ // 结束状态 0-正常 1-结束
63
+ 'end': 0,
64
+ // 阶段 1-9阶段
65
+ 'stage': 1,
66
+ // 微信/公众号消息ID
67
+ 'msgid': '',
68
+ // 更新时间
69
+ 'update_time': '',
70
+ // 创建时间
71
+ 'create_time': '',
72
+ // 群组
73
+ 'group': '',
74
+ // 消息类型 text-文本 image-图片 voice-语音 video-视频 file-文件 location-位置 link-链接 event-事件 other-其他
75
+ 'msg_type': 'text',
76
+ // 媒体ID,图片、语音、视频、文件
77
+ 'media_id': '',
78
+ // 发信人姓名
79
+ 'name': '',
80
+ // 一般情况下,1永久会话/群、2临时会话/群
81
+ 'type': 1,
82
+ // 指令
83
+ 'cmd': '',
84
+ // 应用ID
85
+ 'appid': '',
86
+ // 发信人
87
+ 'from_user': '',
88
+ // 收信人
89
+ 'to_user': '',
90
+ // 机器人,是否机器人回复
91
+ 'robot': 'system',
92
+ // 会话ID,用于判断是否是同一个会话
93
+ 'chatid': '',
94
+ // 发信人头像
95
+ 'avatar': '',
96
+ // 除指令外,过滤、抽取后的词,多个词用空格分隔
97
+ 'keyword': '',
98
+ // 表单,用于记录用户已填参数,json格式字符串
99
+ 'form': '',
100
+ // 聊天内容
101
+ 'content': '',
102
+ // 消息传递数据,json格式字符串
103
+ 'data': '',
104
+ // 备注信息
105
+ 'note': ''
106
+ };
107
+
108
+ /**
109
+ * 构造函数
110
+ * @param {object} config 配置参数
111
+ * @param {object} parent 父级模块
112
+ */
113
+ constructor(config, parent) {
114
+ super({ ...Cmd.config, ...config }, parent);
115
+ this.list_before = [];
116
+ this.list_check = [];
117
+ this.list_main = [];
118
+ this.list_render = [];
119
+ this.list_after = [];
120
+ // 智能指令工具函数
121
+ this.tools = [];
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Cmd驱动类
127
+ */
128
+ Cmd.prototype.Drive = Drive;
129
+
130
+ /**
131
+ * 初始化
132
+ * @private
133
+ */
134
+ Cmd.prototype._preset = function () {
135
+ // 初始化OpenAI客户端
136
+ this._initOpenAIClient();
137
+ };
138
+
139
+ /**
140
+ * 初始化OpenAI客户端
141
+ * @private
142
+ */
143
+ Cmd.prototype._initOpenAIClient = function () {
144
+ var cg = this.config;
145
+
146
+ if (cg.ai && cg.api_key) {
147
+ try {
148
+ this.client = new OpenAI({
149
+ baseURL: cg.base_url,
150
+ apiKey: cg.api_key
151
+ });
152
+ } catch (error) {
153
+ this.log('error', 'AI客户端初始化失败', error.message);
154
+ this.client = null;
155
+ }
156
+ } else {
157
+ this.client = null;
158
+ }
159
+ };
160
+
161
+ /**
162
+ * 构建完整指令列表
163
+ */
164
+ Cmd.prototype._fullList = async function () {
165
+ this.list_before.clear();
166
+ this.list_check.clear();
167
+ this.list_main.clear();
168
+ this.list_render.clear();
169
+ this.list_after.clear();
170
+
171
+ let infos = this.getInfos();
172
+ for (var i = 0; i < infos.length; i++) {
173
+ var info = infos[i];
174
+ if (info.state === 1) {
175
+ let mod = this.getMod(info.name);
176
+ if (mod) {
177
+ switch (mod.config.tense) {
178
+ case 'before':
179
+ this.list_before.push(info);
180
+ break;
181
+ case 'check':
182
+ this.list_check.push(info);
183
+ break;
184
+ case 'render':
185
+ this.list_render.push(info);
186
+ break;
187
+ case 'after':
188
+ this.list_after.push(info);
189
+ break;
190
+ default:
191
+ this.list_main.push(info);
192
+ break;
193
+ }
194
+ }
195
+ }
196
+ }
197
+ };
198
+
199
+ /**
200
+ * 下达指令
201
+ * @param {string} name 名称
202
+ * @param {number} state 状态
203
+ * @param {...any} params 参数集合
204
+ * @returns {object|string} 返回指令执行结果
205
+ */
206
+ Cmd.prototype.cmd = async function (name, state, ...params) {
207
+ var obj = this.get(name);
208
+ if (!obj) {
209
+ return '错误: 指令不存在';
210
+ }
211
+ return await obj.call('cmd', state, ...params);
212
+ };
213
+
214
+ /**
215
+ * 新建消息对象
216
+ * @returns {object} 返回新建的消息对象
217
+ */
218
+ Cmd.prototype.newMsg = function () {
219
+ return { ...Cmd.msg };
220
+ };
221
+
222
+ /**
223
+ * 更新后
224
+ * @param {string} dir_path 目录路径
225
+ */
226
+ Cmd.prototype.updateAfter = async function (dir_path) {
227
+ // 构建完整指令列表
228
+ this._fullList();
229
+ // 构建指令工具函数
230
+ this.tools = this._buildTools();
231
+ };
232
+
233
+ /**
234
+ * 获取智能指令的工具函数
235
+ * @param {number} index 当前阶段ID
236
+ * @returns {Array} 返回工具函数数组
237
+ */
238
+ Cmd.prototype._buildTools = function (index = 0) {
239
+ let tools = [];
240
+ for (var i = 0; i < this.list_main.length; i++) {
241
+ var info = this.list_main[i];
242
+ if (info.state === 1) {
243
+ let mod = this.getMod(info.name);
244
+ if (mod) {
245
+ let tool = this._buildTool(mod.config, index);
246
+ if (tool) {
247
+ tools.push(tool);
248
+ }
249
+ }
250
+ }
251
+ }
252
+ return tools;
253
+ };
254
+
255
+ /**
256
+ * 构建智能指令工具函数
257
+ * @param {object} o 指令配置项
258
+ * @param {number} index 当前阶段ID
259
+ * @returns {object|null} 返回构建的工具函数对象,若失败则返回null
260
+ */
261
+ Cmd.prototype._buildTool = function (o, index = 0) {
262
+ try {
263
+ let description = o.title + "," + o.description;
264
+ if (o.example) {
265
+ description += ",例如:" + o.example;
266
+ }
267
+ let tool = {
268
+ // 类型
269
+ type: 'function',
270
+ // 函数定义
271
+ function: {
272
+ // 函数名称
273
+ name: o.name,
274
+ // 函数描述
275
+ description
276
+ },
277
+ // 启用结构化输出
278
+ strict: true
279
+ }
280
+ let pm = this._buildParams(o.stage, index);
281
+ if (pm) {
282
+ let { props, required } = pm;
283
+ tool.function.parameters = {
284
+ type: 'object',
285
+ properties: props,
286
+ required,
287
+ // 配合 strict 模式
288
+ additionalProperties: false
289
+ }
290
+ }
291
+ return tool;
292
+ } catch (error) {
293
+ this.log('error', `${o.name} 构建工具函数失败`, error);
294
+ return null;
295
+ }
296
+ };
297
+
298
+ /**
299
+ * 构建智能指令的参数
300
+ * @param {array} stage 指令阶段对象
301
+ * @param {number} index 当前阶段索引
302
+ * @returns {object} 返回当前阶段的参数对象
303
+ * @private
304
+ */
305
+ Cmd.prototype._buildParams = function (stage, index) {
306
+ if (!stage || index < 0 || !stage.length || index >= stage.length) {
307
+ return null
308
+ }
309
+ let props = {};
310
+ let required = [];
311
+ var list = stage[index].param;
312
+ for (let i = 0; i < list.length; i++) {
313
+ let o = list[i];
314
+ let description = o.title + "," + o.desc;
315
+ if (o.example) {
316
+ description += ",例如:" + o.example;
317
+ }
318
+ if (o.name) {
319
+ props[o.name] = {
320
+ type: o.type || 'string',
321
+ description
322
+ };
323
+ if (o.required) {
324
+ required.push(o.name);
325
+ }
326
+ }
327
+ }
328
+ return {
329
+ props,
330
+ required
331
+ };
332
+ };
333
+
334
+ /**
335
+ * 调用AI模型(公开通用)
336
+ * @param {array} messages 消息对象数组
337
+ * @param {array} tools 工具函数数组
338
+ * @param {string} model 模型名称
339
+ * @returns {object|string} 返回AI模型的响应消息对象,若失败则返回错误信息字符串
340
+ */
341
+ Cmd.prototype.postToAI = async function (messages, tools = [], model = '') {
342
+ if (!this.client) {
343
+ return '错误: AI模型未初始化';
344
+ }
345
+ try {
346
+ let cg = this.config;
347
+ let body = {
348
+ model: model || cg.model,
349
+ messages,
350
+ temperature: cg.temperature,
351
+ max_tokens: cg.max_tokens || 2048,
352
+ stream: false
353
+ };
354
+ if (tools && tools.length > 0) {
355
+ body.tools = tools;
356
+ body.tool_choice = 'auto';
357
+ }
358
+ return res = await this.client.chat.completions.create(body);
359
+ } catch (error) {
360
+ this.log('error', 'AI API调用失败', error.message);
361
+
362
+ // 根据错误类型提供更具体的提示
363
+ if (error.code === 'insufficient_quota' || error.status === 402) {
364
+ return '抱歉,API配额不足,请检查账户余额';
365
+ } else if (error.code === 'invalid_api_key' || error.status === 401) {
366
+ return 'API密钥无效,请检查配置';
367
+ } else if (error.status === 429) {
368
+ return '请求过于频繁,请稍后重试';
369
+ } else {
370
+ return '抱歉,AI服务暂时不可用,请稍后再试';
371
+ }
372
+ }
373
+ };
374
+
375
+ /**
376
+ * 发布消息到AI模型
377
+ * @param {object} msg 消息对象
378
+ * @param {object} db 数据库对象
379
+ * @returns {object|string} 返回AI模型的响应消息对象,若失败则返回错误信息字符串
380
+ * @private
381
+ */
382
+ Cmd.prototype.callAI = async function (msg, db) {
383
+ if (!msg || !msg.content) {
384
+ return '错误: 消息内容不能为空';
385
+ }
386
+ msg.robot = this.config.ai;
387
+ let content = '';
388
+ var messages = await this._buildMessages(msg, db);
389
+ if (!messages || messages.length === 0) {
390
+ throw new Error('消息数组不能为空');
391
+ }
392
+
393
+ // 最大迭代次数限制,防止无限循环
394
+ const max_iterations = 10;
395
+ let iteration_count = 0;
396
+ let has_tool_calls = false;
397
+
398
+ do {
399
+ has_tool_calls = false;
400
+ iteration_count++;
401
+
402
+ // 调用AI模型,始终包含工具函数以确保AI返回标准格式
403
+ let res = await this.postToAI(messages, this.tools);
404
+ if (!res || !res.choices || res.choices.length === 0) {
405
+ throw new Error('AI模型响应为空');
406
+ }
407
+
408
+ let message = res.choices[0].message;
409
+ messages.push(message);
410
+
411
+ // 检查是否有工具调用
412
+ if (message.tool_calls && message.tool_calls.length > 0) {
413
+ has_tool_calls = true;
414
+
415
+ // 处理工具调用,返回工具调用信息
416
+ let rets = await this._handleToolCalls(msg, db, message.tool_calls);
417
+
418
+ if (!rets || rets.length === 0) {
419
+ this.log('warn', '处理工具调用失败', rets);
420
+ // 如果工具调用失败,移除工具调用相关的消息,然后让AI直接回复
421
+ // 保留系统消息和用户消息,移除AI的工具调用响应
422
+ messages = messages.filter(msg => msg.role !== 'assistant' || !msg.tool_calls);
423
+ // 重新调用AI,这次不包含工具函数,让AI直接回复
424
+ let direct_res = await this.postToAI(messages, []);
425
+ if (direct_res && direct_res.choices && direct_res.choices.length > 0) {
426
+ let direct_message = direct_res.choices[0].message;
427
+ content = direct_message.content || '抱歉,我无法处理这个请求';
428
+ // 添加直接回复到消息上下文
429
+ messages.push(direct_message);
430
+ has_tool_calls = false; // 结束循环
431
+ } else {
432
+ content = '抱歉,AI服务暂时不可用,请稍后再试';
433
+ has_tool_calls = false; // 结束循环
434
+ }
435
+ } else {
436
+ // 将工具调用结果添加到消息上下文
437
+ messages = messages.concat(rets);
438
+ }
439
+ } else {
440
+ // 没有工具调用,获取最终响应内容
441
+ content = message.content || '错误:AI未提供有效响应';
442
+ }
443
+
444
+ // 防止无限循环
445
+ if (iteration_count >= max_iterations) {
446
+ this.log('warn', '达到最大迭代次数限制', iteration_count);
447
+ if (!content) {
448
+ content = '错误:达到最大处理次数限制,请简化您的请求';
449
+ }
450
+ break;
451
+ }
452
+
453
+ } while (has_tool_calls && msg.robot);
454
+
455
+ // 保存指令执行日志
456
+ await this.saveHistory(msg, db, messages);
457
+ return content;
458
+ };
459
+
460
+ /**
461
+ * 构建消息数组
462
+ * @param {object} msg 消息对象
463
+ * @param {object} db 数据库对象
464
+ * @returns {array} 返回构建的消息数组
465
+ * @private
466
+ */
467
+ Cmd.prototype._buildMessages = async function (msg, db) {
468
+ if (!msg || !msg.content) {
469
+ return [];
470
+ }
471
+ var messages = await this.getHistory(msg, db);
472
+ if (!messages || messages.length === 0) {
473
+ messages = [];
474
+ let system_prompt = this._getSystemPrompt();
475
+ messages.push({
476
+ role: 'system',
477
+ content: system_prompt
478
+ });
479
+ }
480
+ messages.push({
481
+ role: 'user',
482
+ content: msg.content
483
+ });
484
+ return messages;
485
+ };
486
+
487
+ /**
488
+ * 获取系统提示
489
+ * @returns {string} 返回系统提示字符串
490
+ * @private
491
+ */
492
+ Cmd.prototype._getSystemPrompt = function () {
493
+ // 获取个性提示词
494
+ let personality_prompt = this._getPersonalityPrompt();
495
+
496
+ // 获取规范提示词
497
+ let standard_prompt = this._getStandardPrompt();
498
+
499
+ // 合并个性提示和规范提示
500
+ let system_prompt = `${personality_prompt}\n${standard_prompt}`;
501
+ return system_prompt;
502
+ };
503
+
504
+ /**
505
+ * 获取个性提示词
506
+ * @returns {string} 返回个性提示字符串
507
+ * @private
508
+ */
509
+ Cmd.prototype._getPersonalityPrompt = function () {
510
+ let prompt = this.config.personality_prompt;
511
+ if (!prompt) {
512
+ prompt = `你是一个专业的智能指令转换专家,具备以下核心能力:
513
+
514
+ ## 角色定位
515
+ - 智能指令解析专家,擅长将自然语言转换为结构化指令
516
+ - 上下文理解大师,能够基于会话历史和状态进行智能判断
517
+ - 多模态消息处理专家,支持文本、图片、语音、文件等多种消息类型
518
+
519
+ ## 核心能力
520
+ 1. **自然语言理解**:准确理解用户意图,识别关键指令和参数
521
+ 2. **上下文感知**:利用消息历史、会话状态、表单数据等上下文信息
522
+ 3. **指令映射**:将用户请求映射到合适的系统指令和工具函数
523
+ 4. **参数提取**:自动提取和补全指令执行所需的参数
524
+ 5. **多步骤规划**:处理复杂的多步骤指令执行场景
525
+
526
+ ## 专业特性
527
+ - 响应速度快,判断准确,能够处理复杂的指令转换场景
528
+ - 具备良好的容错能力,能够处理模糊或不完整的用户输入
529
+ - 支持个性化定制,能够根据不同的用户和场景调整响应策略
530
+
531
+ ## 工具调用失败处理策略
532
+ - 当系统工具调用失败时,基于自己的知识库直接回答用户问题
533
+ - 回复时要自然流畅,不要提及工具调用失败或技术细节
534
+ - 对于天气查询:直接提供一般性天气信息、季节特点或穿衣建议,就像自己知道这些信息一样
535
+ - 对于时间查询:直接提供当前时间或相关时间信息
536
+ - 对于计算问题:直接计算结果并给出答案
537
+ - 对于其他问题:基于常识和经验提供有用的回答
538
+ - 避免提及任何技术限制,保持回复的自然性和实用性`;
539
+ }
540
+ return prompt;
541
+ };
542
+
543
+ /**
544
+ * 获取规范提示词
545
+ * @returns {string} 返回规范提示字符串
546
+ * @private
547
+ */
548
+ Cmd.prototype._getStandardPrompt = function () {
549
+ let prompt = this.config.standard_prompt;
550
+ if (!prompt) {
551
+ prompt = `
552
+ ## 消息上下文信息
553
+ 你可以利用以下消息上下文信息来更好地理解用户意图:
554
+
555
+ ### 基础消息属性
556
+ - **消息类型**: 文本、图片、语音、视频、文件、位置、链接、事件等
557
+ - **消息内容**: 原始消息文本、媒体文件URL、文件信息等
558
+ - **时间信息**: 消息发送时间、创建时间、更新时间
559
+
560
+ ### 会话上下文
561
+ - **会话类型**: 群组、私聊、临时会话、公众号会话
562
+ - **参与者信息**: 发信人ID、收信人ID、机器人标识、群组成员
563
+ - **会话状态**: 会话ID、会话阶段、结束状态、活跃状态
564
+
565
+ ### 历史状态
566
+ - **关键词历史**: 用户历史关键词、常用指令模式
567
+ - **表单数据**: 已填写的表单字段、待补充的参数
568
+ - **备注信息**: 用户备注、会话标签、自定义属性
569
+
570
+ ## 智能指令映射规则
571
+
572
+ ### 1. 消息类型映射规则
573
+ - **文本消息**:
574
+ - 优先匹配文本处理指令(搜索、翻译、计算等)
575
+ - 识别指令关键词(如"搜索"、"查询"、"计算"等)
576
+ - 支持自然语言指令(如"帮我找一下资料")
577
+
578
+ - **媒体消息**(图片/语音/视频):
579
+ - 优先匹配媒体处理指令(识别、分析、转换等)
580
+ - 结合文本内容进行多模态理解
581
+ - 支持媒体文件的分析和提取
582
+
583
+ - **文件消息**:
584
+ - 优先匹配文件处理指令(上传、下载、解析等)
585
+ - 根据文件类型选择合适工具(文档、表格、图片等)
586
+ - 支持文件内容的智能提取
587
+
588
+ - **位置消息**:
589
+ - 优先匹配位置相关指令(导航、周边搜索、地理信息)
590
+ - 结合位置坐标和描述信息
591
+
592
+ ### 2. 会话上下文映射规则
593
+ - **群组消息**:
594
+ - 考虑群组特定的指令和权限
595
+ - 支持群组管理功能(成员管理、公告等)
596
+ - 适应群组交流场景
597
+
598
+ - **私聊消息**:
599
+ - 考虑个人化指令和偏好设置
600
+ - 支持个性化服务和定制功能
601
+ - 保护用户隐私信息
602
+
603
+ - **临时会话**:
604
+ - 考虑临时性指令和一次性服务
605
+ - 快速响应,简化流程
606
+ - 支持会话状态的快速清理
607
+
608
+ ### 3. 历史状态映射规则
609
+ - **阶段信息**:
610
+ - 根据当前阶段选择合适的指令流程
611
+ - 支持多步骤指令的连续执行
612
+ - 维护阶段间的上下文连贯性
613
+
614
+ - **表单数据**:
615
+ - 利用已有的表单数据自动补全参数
616
+ - 减少用户重复输入
617
+ - 支持表单数据的智能验证
618
+
619
+ - **关键词历史**:
620
+ - 基于历史关键词理解用户意图
621
+ - 识别用户的使用习惯和偏好
622
+ - 支持个性化推荐和智能补全
623
+
624
+ ## 指令处理流程
625
+
626
+ ### 1. 意图识别阶段
627
+ - 分析用户输入的自然语言
628
+ - 识别关键指令词和参数
629
+ - 结合上下文信息理解真实意图
630
+
631
+ ### 2. 指令映射阶段
632
+ - 将用户意图映射到系统指令
633
+ - 选择合适的工具函数
634
+ - 确定指令执行优先级
635
+
636
+ ### 3. 参数处理阶段
637
+ - 提取和验证指令参数
638
+ - 补全缺失的参数信息
639
+ - 处理参数格式转换
640
+
641
+ ### 4. 执行规划阶段
642
+ - 规划指令执行步骤
643
+ - 处理多步骤指令场景
644
+ - 考虑异常情况和回退策略
645
+
646
+ ## 特别注意
647
+
648
+ ### 智能判断原则
649
+ - 充分利用所有可用上下文信息
650
+ - 优先考虑最相关的指令映射
651
+ - 支持模糊匹配和容错处理
652
+
653
+ ### 用户体验优化
654
+ - 减少用户输入,智能补全参数
655
+ - 提供清晰的指令反馈
656
+ - 支持指令的撤销和重做
657
+
658
+ ### 错误处理机制
659
+ - 识别和处理无效指令
660
+ - 提供友好的错误提示
661
+ - 支持指令的重新解释和修正
662
+
663
+ ### 工具调用失败处理
664
+ - 当工具调用失败时,基于自己的知识直接回答用户问题
665
+ - 回复时要自然流畅,不要提及工具调用失败或技术细节
666
+ - 对于常见问题(如天气、时间、计算等),直接提供一般性信息或建议,就像自己知道这些信息一样
667
+ - 避免重复工具调用过程,直接给出有用的回答
668
+ - 如果无法提供准确信息,可以给出替代方案或建议,但不要暴露技术限制
669
+
670
+ ### 性能考虑
671
+ - 快速响应,减少等待时间
672
+ - 优化指令映射算法
673
+ - 支持并发指令处理`;
674
+ }
675
+ return prompt;
676
+ };
677
+
678
+ /**
679
+ * 执行指令
680
+ * @param {string} cmd 指令字符串
681
+ * @param {string} method 方法名
682
+ * @param {...*} args 指令参数
683
+ * @returns {string} 返回指令执行结果
684
+ * @private
685
+ */
686
+ Cmd.prototype._exec = async function (tense, cmd, method, ...args) {
687
+ var list = this['list_' + tense];
688
+ if (!list) {
689
+ throw new Error(` 不存在时态: ${tense}`);
690
+ }
691
+ // 查找指令
692
+ for (var i = 0; i < list.length; i++) {
693
+ var info = list[i];
694
+ if (info.name === cmd) {
695
+ let mod = this.getMod(info.name);
696
+ if (mod) {
697
+ return await mod.call(method, ...args);
698
+ }
699
+ }
700
+ }
701
+ };
702
+
703
+ /**
704
+ * 推送工具调用消息
705
+ * @param {*} ret 工具调用执行结果
706
+ * @param {string} tool_call_id 工具调用ID
707
+ * @returns {object} 返回工具调用消息对象
708
+ * @private
709
+ */
710
+ Cmd.prototype.getMessage = function (ret, tool_call_id) {
711
+ if (typeof ret === 'object') {
712
+ if (ret.error) {
713
+ return {
714
+ role: 'tool',
715
+ tool_call_id,
716
+ content: JSON.stringify({ error: ret.error.message }),
717
+ }
718
+ }
719
+ ret = JSON.stringify(ret);
720
+ }
721
+ else if (typeof ret === 'string') {
722
+ if (this._isError(ret)) {
723
+ // 记录工具调用信息
724
+ return {
725
+ role: 'tool',
726
+ tool_call_id,
727
+ content: JSON.stringify({ error: ret })
728
+ }
729
+ }
730
+ }
731
+ // 记录工具调用信息
732
+ return {
733
+ role: 'tool',
734
+ tool_call_id,
735
+ content: ret
736
+ }
737
+ };
738
+
739
+ /**
740
+ * 判断是否为错误信息
741
+ * @param {string} content 内容字符串
742
+ * @returns {boolean} 返回是否为错误信息
743
+ * @private
744
+ */
745
+ Cmd.prototype._isError = function (content) {
746
+ return content.startsWith('错误') || content.startsWith('不能为');
747
+ };
748
+
749
+ /**
750
+ * 处理工具调用
751
+ * @description 处理消息中的工具调用,执行对应的指令并返回结果
752
+ * @param {object} msg 消息对象,包含工具调用信息
753
+ * @param {object} db 数据管理器,用于存储和检索数据
754
+ * @param {Array} tool_calls 工具调用数组,每个元素包含工具调用的信息
755
+ * @returns {string} 返回工具调用处理结果,格式为JSON字符串
756
+ * @private
757
+ */
758
+ Cmd.prototype._handleToolCalls = async function (msg, db, tool_calls) {
759
+ var messages = [];
760
+
761
+ for (var i = 0; i < tool_calls.length; i++) {
762
+ var tool = tool_calls[i];
763
+ var cmd = tool.function.name;
764
+ var form = {};
765
+ try {
766
+ // 解析函数参数
767
+ var args = tool.function.arguments;
768
+ if (args) {
769
+ if (typeof args === 'string') {
770
+ form = JSON.parse(args);
771
+ } else {
772
+ form = args;
773
+ }
774
+ }
775
+ msg.form = form;
776
+ var ret = await this._exec('main', cmd, 'main', msg, db);
777
+ if (ret) {
778
+ messages.push(this.getMessage(ret, tool.id));
779
+ }
780
+ } catch (error) {
781
+ this.log('error', `解析工具调用参数失败: ${cmd} `, error.message);
782
+ messages.push({
783
+ role: 'tool',
784
+ tool_call_id: tool.id,
785
+ content: JSON.stringify({ error: `工具调用参数解析失败: ${error.message} ` })
786
+ });
787
+ }
788
+ }
789
+ return messages;
790
+ };
791
+
792
+ /**
793
+ * 获取指令执行日志
794
+ * @param {object} msg 消息对象,包含指令信息
795
+ * @param {object} db 数据管理器,用于存储和检索数据
796
+ * @returns {Array} 返回指令执行日志数组
797
+ */
798
+ Cmd.prototype.getHistory = async function (msg, db) {
799
+ var key = this._getKey(msg);
800
+ var logs = await $.cache.get(key);
801
+ if (!logs) {
802
+ logs = [];
803
+ }
804
+ else if (typeof logs === 'string') {
805
+ logs = JSON.parse(logs);
806
+ }
807
+ return logs;
808
+ };
809
+
810
+ /**
811
+ * 保存指令执行日志
812
+ * @param {object} msg 消息对象,包含指令信息
813
+ * @param {object} db 数据管理器,用于存储和检索数据
814
+ * @param {Array} logs 指令执行日志数组
815
+ * @private
816
+ */
817
+ Cmd.prototype.saveHistory = async function (msg, db, logs) {
818
+ var key = this._getKey(msg);
819
+ await $.cache.set(key, logs, this.config.interval);
820
+ };
821
+
822
+ /**
823
+ * 获取指令执行日志缓存键
824
+ * @param {object} msg 消息内容
825
+ * @returns {string} 返回指令执行日志缓存键
826
+ */
827
+ Cmd.prototype._getKey = function (msg) {
828
+ return this.config.cache_prefix + msg.form + "_" + msg.to_user + "_" + msg.group;
829
+ };
830
+
831
+ /**
832
+ * 执行指令
833
+ * @param {object} msg 消息对象,包含指令信息
834
+ * @param {object} db 数据管理器,用于存储和检索数据
835
+ * @returns {string} 返回指令执行结果,格式为JSON字符串
836
+ * @private
837
+ */
838
+ Cmd.prototype.run = async function (msg, db) {
839
+ // 判断是否含有消息和消息正文
840
+ if (!msg || !msg.content) {
841
+ return;
842
+ }
843
+
844
+ // 初始化数据库配置
845
+ db.table = this.config.table;
846
+ db.key = this.config.key;
847
+
848
+ // 统一的指令处理流程
849
+ var ret = await this._run(msg, db);
850
+
851
+ // 记录执行结果
852
+ db.ret = ret;
853
+ return ret;
854
+ };
855
+
856
+ /**
857
+ * 指令行为主函数
858
+ * @param {object} msg 消息
859
+ * @param {object} db 数据管理器,如: { next: async function{}, ret: {} }
860
+ * @returns {object} 执行结果
861
+ * @private
862
+ */
863
+ Cmd.prototype._run = async function (msg, db) {
864
+ return null;
865
+ var cg = this.config;
866
+ if (cg.ai) {
867
+ msg.robot = cg.ai;
868
+ let ret = await this.callAI(msg, db);
869
+ return ret;
870
+ }
871
+ else {
872
+ let ret = await this._exec('main', msg.content, 'main', msg, db);
873
+ return ret;
874
+ }
875
+ };
876
+
877
+ /**
878
+ * 执行指令前处理
879
+ * @param {object} msg 消息对象
880
+ * @param {object} db 数据库对象
881
+ * @returns {object|string} 返回指令执行结果
882
+ */
883
+ Cmd.prototype._runBefore = async function (msg, db) {
884
+ db.logs = await this._getLogs(msg, db);
885
+ await this._fullMsg(msg, db);
886
+ return await this.runSub(msg, db, 'before');
887
+ };
888
+
889
+ /**
890
+ * 执行主指令
891
+ * @param {object} msg 消息
892
+ * @param {object} db 数据管理器
893
+ * @returns {object} 返回执行结果
894
+ * @private
895
+ */
896
+ Cmd.prototype._runMain = async function (msg, db) {
897
+ // 先判断本次内容是否为指令
898
+ var ret_main = await this.runSub(msg, db, 'main');
899
+ if (ret_main) {
900
+ return ret_main;
901
+ }
902
+ // 获取历史未完成的指令,拼接本次内容并执行
903
+ var log = await this.getContext(msg, db);
904
+ if (!log) {
905
+ return null;
906
+ }
907
+ return await this.runSub(m, db, 'main');
908
+ };
909
+
910
+ /**
911
+ * 执行后时态指令
912
+ * @param {object} msg 消息
913
+ * @param {object} db 数据管理器
914
+ * @returns {object|string} 返回指令执行结果
915
+ */
916
+ Cmd.prototype._runAfter = async function (msg, db) {
917
+ var ret = await this.runSub(msg, db, 'after');
918
+ return ret;
919
+ };
920
+
921
+ /**
922
+ * 补全消息
923
+ * @param {object} msg 消息对象
924
+ * @param {object} db 数据管理器
925
+ * @returns {object} 返回合并后的消息对象
926
+ */
927
+ Cmd.prototype._fullMsg = function (msg, db) {
928
+
929
+ };
930
+
931
+ /**
932
+ * 执行指令
933
+ * @param {object} msg 消息对象
934
+ * @param {object} db 数据库对象
935
+ * @param {string} tense 时态
936
+ * @returns {object|string} 返回指令执行结果
937
+ */
938
+ Cmd.prototype.runSub = async function (msg, db, tense = 'main') {
939
+ var list = this['list_' + tense];
940
+ if (!list) {
941
+ return;
942
+ }
943
+ var ret;
944
+ for (var i = 0, info; info = list[i++];) {
945
+ if (info.state === 1) {
946
+ let mod = this.getMod(info.name);
947
+ if (mod) {
948
+ ret = await mod.run(msg, db);
949
+ if (ret) {
950
+ db.ret = ret;
951
+ // 如果匹配指令则将该消息定义为使用该指令
952
+ msg.cmd = info.name;
953
+ if (mod.config.end) {
954
+ break;
955
+ }
956
+ }
957
+ }
958
+ }
959
+ }
960
+ return ret;
961
+ };
962
+
963
+ /**
964
+ * 获取对话历史
965
+ * @param {object} msg 当前消息
966
+ * @param {object} db 数据库对象
967
+ * @returns {Array} 返回历史消息数组
968
+ */
969
+ Cmd.prototype._getLogs = async function (msg, db) {
970
+ // 先尝试从缓存中获取对话历史
971
+ var logs = await this._getLogsFromCache(msg);
972
+ if (logs.length > 0) {
973
+ return logs;
974
+ }
975
+
976
+ // 如果缓存中没有,从数据库查询
977
+ logs = await this._getLogsFromDB(msg, db);
978
+ if (logs.length > 0) {
979
+ // 缓存查询结果
980
+ await this._setLogsToCache(msg, logs);
981
+ }
982
+
983
+ return logs;
984
+ };
985
+
986
+ /**
987
+ * 从数据库中获取对话历史
988
+ * @param {object} msg 当前消息
989
+ * @param {object} db 数据库对象
990
+ * @returns {Array} 返回历史消息数组
991
+ * @private
992
+ */
993
+ Cmd.prototype._getLogsFromDB = async function (msg, db) {
994
+ var cg = this.config;
995
+ var max_turns = cg.max_turns;
996
+
997
+ // 基于实际数据库字段查询对话记录
998
+ var query = {
999
+ from_user: msg.from_user,
1000
+ to_user: msg.to_user,
1001
+ group: msg.group,
1002
+ type: msg.type
1003
+ };
1004
+
1005
+ // 如果当前消息有chatid,优先基于chatid查询同一个对话会话
1006
+ if (msg.chatid) {
1007
+ query.chatid = msg.chatid;
1008
+ }
1009
+
1010
+ var db1 = db.new(cg.table, cg.key);
1011
+ var logs = await db1.getList(query, '`time_create` desc', max_turns * 2);
1012
+ return logs;
1013
+ };
1014
+
1015
+ /**
1016
+ * 从缓存中获取对话历史
1017
+ * @param {object} msg 当前消息
1018
+ * @returns {Array} 返回历史消息数组
1019
+ * @private
1020
+ */
1021
+ Cmd.prototype._getLogsFromCache = async function (msg) {
1022
+ var logs = await $.cache.get(msg.chatid || this._getKey(msg));
1023
+ if (!logs) {
1024
+ logs = [];
1025
+ }
1026
+ else if (typeof logs === 'string') {
1027
+ logs = JSON.parse(logs);
1028
+ }
1029
+ return logs;
1030
+ };
1031
+
1032
+ /* 导出指令 */
1033
+ exports.Cmd = Cmd;
1034
+
1035
+ /**
1036
+ * Cmd事件池
1037
+ */
1038
+ if (!$.pool.cmd) {
1039
+ $.pool.cmd = {};
1040
+ }
1041
+
1042
+ /**
1043
+ * Cmd管理器,用于创建缓存
1044
+ * @param {string} scope 作用域
1045
+ * @param {string} title 标题
1046
+ * @returns {object} 返回一个缓存类
1047
+ */
1048
+ function cmdAdmin(scope, title) {
1049
+ var sc = scope || $.val.scope + '';
1050
+ var obj = $.pool.cmd[sc];
1051
+ if (!obj) {
1052
+ $.pool.cmd[sc] = new Cmd({
1053
+ name: sc,
1054
+ title: title || sc
1055
+ });
1056
+ obj = $.pool.cmd[sc];
1057
+ }
1058
+ return obj;
1059
+ }
1060
+
1061
+ /**
1062
+ * @module 导出Cmd管理器
1063
+ */
1064
+ if ($.admin) {
1065
+ $.admin.cmd = cmdAdmin;
1066
+ }