@zhin.js/core 1.1.34 → 1.1.35

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 (386) hide show
  1. package/README.md +121 -65
  2. package/lib/adapter.d.ts +72 -23
  3. package/lib/adapter.js +222 -62
  4. package/lib/built/adapter-process.d.ts +20 -5
  5. package/lib/built/adapter-process.js +54 -7
  6. package/lib/built/agent-preset.d.ts +1 -2
  7. package/lib/built/agent-preset.js +1 -2
  8. package/lib/built/ai-access.d.ts +36 -0
  9. package/lib/built/ai-access.js +46 -0
  10. package/lib/built/ai-outbound/adapter-access.d.ts +3 -0
  11. package/lib/built/ai-outbound/adapter-access.js +9 -0
  12. package/lib/built/ai-outbound/extensions/onebot-keyboard.d.ts +2 -0
  13. package/lib/built/ai-outbound/extensions/onebot-keyboard.js +67 -0
  14. package/lib/built/ai-outbound/extensions/qq-message.d.ts +3 -0
  15. package/lib/built/ai-outbound/extensions/qq-message.js +23 -0
  16. package/lib/built/ai-outbound/index.d.ts +9 -0
  17. package/lib/built/ai-outbound/index.js +9 -0
  18. package/lib/built/ai-outbound/parse.d.ts +13 -0
  19. package/lib/built/ai-outbound/parse.js +104 -0
  20. package/lib/built/ai-outbound/plain-mention-rewrite.d.ts +6 -0
  21. package/lib/built/ai-outbound/plain-mention-rewrite.js +37 -0
  22. package/lib/built/ai-outbound/prompt.d.ts +11 -0
  23. package/lib/built/ai-outbound/prompt.js +44 -0
  24. package/lib/built/ai-outbound/resolve.d.ts +4 -0
  25. package/lib/built/ai-outbound/resolve.js +64 -0
  26. package/lib/built/ai-outbound/structured-detect.d.ts +3 -0
  27. package/lib/built/ai-outbound/structured-detect.js +6 -0
  28. package/lib/built/ai-outbound/types.d.ts +58 -0
  29. package/lib/built/ai-outbound/types.js +5 -0
  30. package/lib/built/ai-trigger.d.ts +17 -17
  31. package/lib/built/ai-trigger.js +65 -70
  32. package/lib/built/authorization.d.ts +10 -0
  33. package/lib/built/authorization.js +76 -0
  34. package/lib/built/command.d.ts +9 -5
  35. package/lib/built/command.js +20 -7
  36. package/lib/built/common-adapter-tools.d.ts +35 -29
  37. package/lib/built/common-adapter-tools.js +83 -67
  38. package/lib/built/component.d.ts +1 -3
  39. package/lib/built/component.js +2 -4
  40. package/lib/built/config.d.ts +4 -5
  41. package/lib/built/config.js +26 -9
  42. package/lib/built/connect-endpoint-instance.d.ts +17 -0
  43. package/lib/built/connect-endpoint-instance.js +42 -0
  44. package/lib/built/database.d.ts +5 -3
  45. package/lib/built/database.js +10 -4
  46. package/lib/built/dispatcher.d.ts +10 -8
  47. package/lib/built/dispatcher.js +31 -9
  48. package/lib/built/endpoint-commands.d.ts +3 -0
  49. package/lib/built/endpoint-commands.js +99 -0
  50. package/lib/built/endpoint-lifecycle-service.d.ts +28 -0
  51. package/lib/built/endpoint-lifecycle-service.js +242 -0
  52. package/lib/built/endpoint-lifecycle.d.ts +27 -0
  53. package/lib/built/endpoint-lifecycle.js +36 -0
  54. package/lib/built/endpoint-manager.d.ts +34 -0
  55. package/lib/built/endpoint-manager.js +1 -0
  56. package/lib/built/generated-qrcode.d.ts +24 -0
  57. package/lib/built/generated-qrcode.js +45 -0
  58. package/lib/built/generic-segment-mapper.d.ts +4 -0
  59. package/lib/built/generic-segment-mapper.js +190 -0
  60. package/lib/built/html-renderer-loader.d.ts +13 -0
  61. package/lib/built/html-renderer-loader.js +33 -0
  62. package/lib/built/html-segment-fallback.d.ts +2 -2
  63. package/lib/built/html-segment-fallback.js +0 -1
  64. package/lib/built/html-to-text.d.ts +0 -1
  65. package/lib/built/html-to-text.js +15 -15
  66. package/lib/built/inbound-pipeline.d.ts +37 -0
  67. package/lib/built/inbound-pipeline.js +63 -0
  68. package/lib/built/inbound-runner.d.ts +0 -1
  69. package/lib/built/inbound-runner.js +0 -3
  70. package/lib/built/interactive-segment-contract.d.ts +6 -0
  71. package/lib/built/interactive-segment-contract.js +9 -0
  72. package/lib/built/interactive-segments/action.d.ts +17 -0
  73. package/lib/built/interactive-segments/action.js +69 -0
  74. package/lib/built/interactive-segments/button-spec.d.ts +10 -0
  75. package/lib/built/interactive-segments/button-spec.js +21 -0
  76. package/lib/built/interactive-segments/fallback-store.d.ts +29 -0
  77. package/lib/built/interactive-segments/fallback-store.js +63 -0
  78. package/lib/built/interactive-segments/handlers.d.ts +16 -0
  79. package/lib/built/interactive-segments/handlers.js +74 -0
  80. package/lib/built/interactive-segments/index.d.ts +8 -0
  81. package/lib/built/interactive-segments/index.js +8 -0
  82. package/lib/built/interactive-segments/keyboard-segment.d.ts +11 -0
  83. package/lib/built/interactive-segments/keyboard-segment.js +12 -0
  84. package/lib/built/interactive-segments/onebot-keyboard.d.ts +7 -0
  85. package/lib/built/interactive-segments/onebot-keyboard.js +51 -0
  86. package/lib/built/interactive-segments/resolve.d.ts +15 -0
  87. package/lib/built/interactive-segments/resolve.js +110 -0
  88. package/lib/built/interactive-segments/types.d.ts +50 -0
  89. package/lib/built/interactive-segments/types.js +9 -0
  90. package/lib/built/introspection-format.d.ts +10 -0
  91. package/lib/built/introspection-format.js +28 -0
  92. package/lib/built/login-assist.d.ts +43 -9
  93. package/lib/built/login-assist.js +113 -11
  94. package/lib/built/management-command-guard.d.ts +15 -0
  95. package/lib/built/management-command-guard.js +25 -0
  96. package/lib/built/message-enrich.d.ts +38 -0
  97. package/lib/built/message-enrich.js +75 -0
  98. package/lib/built/message-filter.d.ts +4 -5
  99. package/lib/built/message-filter.js +5 -7
  100. package/lib/built/optional-peer-import.d.ts +3 -0
  101. package/lib/built/optional-peer-import.js +33 -0
  102. package/lib/built/outbound-media-contract.d.ts +22 -0
  103. package/lib/built/outbound-media-contract.js +10 -0
  104. package/lib/built/outbound-media-utils.d.ts +9 -0
  105. package/lib/built/outbound-media-utils.js +62 -0
  106. package/lib/built/permission.d.ts +3 -7
  107. package/lib/built/permission.js +39 -52
  108. package/lib/built/permit-check.d.ts +7 -0
  109. package/lib/built/permit-check.js +35 -0
  110. package/lib/built/permit-parse.d.ts +16 -0
  111. package/lib/built/permit-parse.js +32 -0
  112. package/lib/built/platform-permit.d.ts +20 -0
  113. package/lib/built/platform-permit.js +91 -0
  114. package/lib/built/queue-im-field-contract.d.ts +7 -2
  115. package/lib/built/queue-im-field-contract.js +13 -4
  116. package/lib/built/rich-segments/adapter-policies.d.ts +9 -0
  117. package/lib/built/rich-segments/adapter-policies.js +27 -0
  118. package/lib/built/rich-segments/base.d.ts +11 -0
  119. package/lib/built/rich-segments/base.js +24 -0
  120. package/lib/built/rich-segments/builtins.d.ts +4 -0
  121. package/lib/built/rich-segments/builtins.js +40 -0
  122. package/lib/built/rich-segments/capabilities.d.ts +6 -0
  123. package/lib/built/rich-segments/capabilities.js +38 -0
  124. package/lib/built/rich-segments/html-segment.d.ts +15 -0
  125. package/lib/built/rich-segments/html-segment.js +62 -0
  126. package/lib/built/rich-segments/index.d.ts +13 -0
  127. package/lib/built/rich-segments/index.js +13 -0
  128. package/lib/built/rich-segments/markdown-segment.d.ts +14 -0
  129. package/lib/built/rich-segments/markdown-segment.js +58 -0
  130. package/lib/built/rich-segments/markdown-to-text.d.ts +3 -0
  131. package/lib/built/rich-segments/markdown-to-text.js +27 -0
  132. package/lib/built/rich-segments/qrcode-segment.d.ts +18 -0
  133. package/lib/built/rich-segments/qrcode-segment.js +73 -0
  134. package/lib/built/rich-segments/registry.d.ts +16 -0
  135. package/lib/built/rich-segments/registry.js +52 -0
  136. package/lib/built/rich-segments/resolve.d.ts +5 -0
  137. package/lib/built/rich-segments/resolve.js +87 -0
  138. package/lib/built/rich-segments/tts-segment.d.ts +13 -0
  139. package/lib/built/rich-segments/tts-segment.js +51 -0
  140. package/lib/built/rich-segments/types.d.ts +79 -0
  141. package/lib/built/rich-segments/types.js +17 -0
  142. package/lib/built/roles.d.ts +4 -5
  143. package/lib/built/roles.js +4 -5
  144. package/lib/built/runtime-io.d.ts +0 -1
  145. package/lib/built/runtime-io.js +0 -1
  146. package/lib/built/schedule.d.ts +54 -0
  147. package/lib/built/schedule.js +112 -0
  148. package/lib/built/schema-endpoint-manager.d.ts +17 -0
  149. package/lib/built/schema-endpoint-manager.js +73 -0
  150. package/lib/built/schema-feature.d.ts +0 -1
  151. package/lib/built/schema-feature.js +1 -3
  152. package/lib/built/segment-contract/assert.d.ts +7 -0
  153. package/lib/built/segment-contract/assert.js +39 -0
  154. package/lib/built/segment-contract/delivery.d.ts +5 -0
  155. package/lib/built/segment-contract/delivery.js +40 -0
  156. package/lib/built/segment-contract/image.d.ts +5 -0
  157. package/lib/built/segment-contract/image.js +10 -0
  158. package/lib/built/segment-contract/index.d.ts +10 -0
  159. package/lib/built/segment-contract/index.js +9 -0
  160. package/lib/built/segment-contract/json-schema.d.ts +28 -0
  161. package/lib/built/segment-contract/json-schema.js +128 -0
  162. package/lib/built/segment-contract/media.d.ts +12 -0
  163. package/lib/built/segment-contract/media.js +22 -0
  164. package/lib/built/segment-contract/mention.d.ts +10 -0
  165. package/lib/built/segment-contract/mention.js +26 -0
  166. package/lib/built/segment-contract/preview.d.ts +3 -0
  167. package/lib/built/segment-contract/preview.js +159 -0
  168. package/lib/built/segment-contract/text.d.ts +7 -0
  169. package/lib/built/segment-contract/text.js +34 -0
  170. package/lib/built/segment-contract/types.d.ts +58 -0
  171. package/lib/built/segment-contract/types.js +1 -0
  172. package/lib/built/segment-contract/validate.d.ts +229 -0
  173. package/lib/built/segment-contract/validate.js +174 -0
  174. package/lib/built/skill.d.ts +0 -1
  175. package/lib/built/skill.js +0 -1
  176. package/lib/built/speech-loader.d.ts +14 -0
  177. package/lib/built/speech-loader.js +32 -0
  178. package/lib/built/tool.d.ts +14 -13
  179. package/lib/built/tool.js +30 -25
  180. package/lib/built/user-interaction.d.ts +30 -0
  181. package/lib/built/user-interaction.js +248 -0
  182. package/lib/command.d.ts +19 -11
  183. package/lib/command.js +42 -11
  184. package/lib/component.d.ts +0 -1
  185. package/lib/component.js +30 -14
  186. package/lib/endpoint-capabilities.d.ts +46 -0
  187. package/lib/endpoint-capabilities.js +55 -0
  188. package/lib/endpoint.d.ts +19 -0
  189. package/lib/endpoint.js +3 -0
  190. package/lib/errors.d.ts +2 -3
  191. package/lib/errors.js +4 -5
  192. package/lib/feature/adapter.d.ts +2 -0
  193. package/lib/feature/adapter.js +2 -0
  194. package/lib/feature/command.d.ts +2 -0
  195. package/lib/feature/command.js +2 -0
  196. package/lib/feature/component.d.ts +2 -0
  197. package/lib/feature/component.js +2 -0
  198. package/lib/feature/handler.d.ts +52 -0
  199. package/lib/feature/handler.js +26 -0
  200. package/lib/feature/middleware.d.ts +2 -0
  201. package/lib/feature/middleware.js +2 -0
  202. package/lib/host-plugin-registry.d.ts +8 -0
  203. package/lib/host-plugin-registry.js +12 -0
  204. package/lib/im-scene.d.ts +29 -0
  205. package/lib/im-scene.js +75 -0
  206. package/lib/im-session-id.d.ts +39 -0
  207. package/lib/im-session-id.js +47 -0
  208. package/lib/index.d.ts +59 -25
  209. package/lib/index.js +53 -31
  210. package/lib/jsx-dev-runtime.d.ts +0 -1
  211. package/lib/jsx-dev-runtime.js +0 -1
  212. package/lib/jsx-runtime.d.ts +1 -1
  213. package/lib/jsx-runtime.js +0 -1
  214. package/lib/jsx.d.ts +19 -22
  215. package/lib/jsx.js +0 -1
  216. package/lib/message.d.ts +16 -10
  217. package/lib/message.js +16 -13
  218. package/lib/models/system-log.d.ts +0 -1
  219. package/lib/models/system-log.js +0 -1
  220. package/lib/models/user.d.ts +0 -1
  221. package/lib/models/user.js +0 -1
  222. package/lib/notice.d.ts +16 -59
  223. package/lib/notice.js +1 -4
  224. package/lib/plugin-context.d.ts +27 -0
  225. package/lib/plugin-context.js +64 -0
  226. package/lib/plugin-runtime/im/contracts.d.ts +191 -0
  227. package/lib/plugin-runtime/im/contracts.js +169 -0
  228. package/lib/plugin-runtime/im/im-runtime.d.ts +177 -0
  229. package/lib/plugin-runtime/im/im-runtime.js +1204 -0
  230. package/lib/plugin-runtime/im/index.d.ts +9 -0
  231. package/lib/plugin-runtime/im/index.js +9 -0
  232. package/lib/plugin-runtime/im/interactive.d.ts +26 -0
  233. package/lib/plugin-runtime/im/interactive.js +46 -0
  234. package/lib/plugin-runtime/im/login-assist-host.d.ts +6 -0
  235. package/lib/plugin-runtime/im/login-assist-host.js +6 -0
  236. package/lib/plugin-runtime/im/message-bus.d.ts +38 -0
  237. package/lib/plugin-runtime/im/message-bus.js +40 -0
  238. package/lib/plugin-runtime/im/message-dispatcher.d.ts +18 -0
  239. package/lib/plugin-runtime/im/message-dispatcher.js +107 -0
  240. package/lib/plugin-runtime/im/outbound-renderer.d.ts +7 -0
  241. package/lib/plugin-runtime/im/outbound-renderer.js +70 -0
  242. package/lib/plugin-runtime/im/outbound-segments.d.ts +72 -0
  243. package/lib/plugin-runtime/im/outbound-segments.js +220 -0
  244. package/lib/plugin-runtime/im/public-api.d.ts +6 -0
  245. package/lib/plugin-runtime/im/public-api.js +6 -0
  246. package/lib/plugin-runtime/im/service-tokens.d.ts +18 -0
  247. package/lib/plugin-runtime/im/service-tokens.js +13 -0
  248. package/lib/plugin.d.ts +34 -24
  249. package/lib/plugin.js +119 -224
  250. package/lib/request.d.ts +17 -61
  251. package/lib/request.js +0 -4
  252. package/lib/{prompt.d.ts → schema-interaction.d.ts} +6 -7
  253. package/lib/{prompt.js → schema-interaction.js} +20 -17
  254. package/lib/side-event/base.d.ts +52 -0
  255. package/lib/side-event/base.js +30 -0
  256. package/lib/side-event/dispatch.d.ts +15 -0
  257. package/lib/side-event/dispatch.js +140 -0
  258. package/lib/side-event/index.d.ts +4 -0
  259. package/lib/side-event/index.js +4 -0
  260. package/lib/side-event/normalize.d.ts +42 -0
  261. package/lib/side-event/normalize.js +121 -0
  262. package/lib/side-event/types.d.ts +23 -0
  263. package/lib/side-event/types.js +55 -0
  264. package/lib/system-event.d.ts +15 -0
  265. package/lib/system-event.js +7 -0
  266. package/lib/tool-zod.d.ts +18 -3
  267. package/lib/tool-zod.js +140 -54
  268. package/lib/types.d.ts +44 -95
  269. package/lib/types.js +0 -1
  270. package/lib/utils.d.ts +61 -13
  271. package/lib/utils.js +66 -25
  272. package/package.json +98 -10
  273. package/lib/adapter.d.ts.map +0 -1
  274. package/lib/adapter.js.map +0 -1
  275. package/lib/agent-prompt.d.ts +0 -37
  276. package/lib/agent-prompt.d.ts.map +0 -1
  277. package/lib/agent-prompt.js +0 -2
  278. package/lib/agent-prompt.js.map +0 -1
  279. package/lib/bot.d.ts +0 -38
  280. package/lib/bot.d.ts.map +0 -1
  281. package/lib/bot.js +0 -2
  282. package/lib/bot.js.map +0 -1
  283. package/lib/built/adapter-process.d.ts.map +0 -1
  284. package/lib/built/adapter-process.js.map +0 -1
  285. package/lib/built/agent-preset.d.ts.map +0 -1
  286. package/lib/built/agent-preset.js.map +0 -1
  287. package/lib/built/ai-trigger.d.ts.map +0 -1
  288. package/lib/built/ai-trigger.js.map +0 -1
  289. package/lib/built/command.d.ts.map +0 -1
  290. package/lib/built/command.js.map +0 -1
  291. package/lib/built/common-adapter-tools.d.ts.map +0 -1
  292. package/lib/built/common-adapter-tools.js.map +0 -1
  293. package/lib/built/component.d.ts.map +0 -1
  294. package/lib/built/component.js.map +0 -1
  295. package/lib/built/config.d.ts.map +0 -1
  296. package/lib/built/config.js.map +0 -1
  297. package/lib/built/cron.d.ts +0 -75
  298. package/lib/built/cron.d.ts.map +0 -1
  299. package/lib/built/cron.js +0 -122
  300. package/lib/built/cron.js.map +0 -1
  301. package/lib/built/database.d.ts.map +0 -1
  302. package/lib/built/database.js.map +0 -1
  303. package/lib/built/dispatcher.d.ts.map +0 -1
  304. package/lib/built/dispatcher.js.map +0 -1
  305. package/lib/built/html-segment-fallback.d.ts.map +0 -1
  306. package/lib/built/html-segment-fallback.js.map +0 -1
  307. package/lib/built/html-to-text.d.ts.map +0 -1
  308. package/lib/built/html-to-text.js.map +0 -1
  309. package/lib/built/inbound-runner.d.ts.map +0 -1
  310. package/lib/built/inbound-runner.js.map +0 -1
  311. package/lib/built/login-assist.d.ts.map +0 -1
  312. package/lib/built/login-assist.js.map +0 -1
  313. package/lib/built/mcp-mesh-registrar.d.ts +0 -9
  314. package/lib/built/mcp-mesh-registrar.d.ts.map +0 -1
  315. package/lib/built/mcp-mesh-registrar.js +0 -17
  316. package/lib/built/mcp-mesh-registrar.js.map +0 -1
  317. package/lib/built/message-filter.d.ts.map +0 -1
  318. package/lib/built/message-filter.js.map +0 -1
  319. package/lib/built/permission.d.ts.map +0 -1
  320. package/lib/built/permission.js.map +0 -1
  321. package/lib/built/prepend-quote-context.d.ts +0 -35
  322. package/lib/built/prepend-quote-context.d.ts.map +0 -1
  323. package/lib/built/prepend-quote-context.js +0 -131
  324. package/lib/built/prepend-quote-context.js.map +0 -1
  325. package/lib/built/queue-im-field-contract.d.ts.map +0 -1
  326. package/lib/built/queue-im-field-contract.js.map +0 -1
  327. package/lib/built/roles.d.ts.map +0 -1
  328. package/lib/built/roles.js.map +0 -1
  329. package/lib/built/runtime-io.d.ts.map +0 -1
  330. package/lib/built/runtime-io.js.map +0 -1
  331. package/lib/built/schema-feature.d.ts.map +0 -1
  332. package/lib/built/schema-feature.js.map +0 -1
  333. package/lib/built/skill.d.ts.map +0 -1
  334. package/lib/built/skill.js.map +0 -1
  335. package/lib/built/tool.d.ts.map +0 -1
  336. package/lib/built/tool.js.map +0 -1
  337. package/lib/command.d.ts.map +0 -1
  338. package/lib/command.js.map +0 -1
  339. package/lib/component.d.ts.map +0 -1
  340. package/lib/component.js.map +0 -1
  341. package/lib/errors.d.ts.map +0 -1
  342. package/lib/errors.js.map +0 -1
  343. package/lib/index.d.ts.map +0 -1
  344. package/lib/index.js.map +0 -1
  345. package/lib/jsx-dev-runtime.d.ts.map +0 -1
  346. package/lib/jsx-dev-runtime.js.map +0 -1
  347. package/lib/jsx-runtime.d.ts.map +0 -1
  348. package/lib/jsx-runtime.js.map +0 -1
  349. package/lib/jsx.d.ts.map +0 -1
  350. package/lib/jsx.js.map +0 -1
  351. package/lib/message-quote.d.ts +0 -11
  352. package/lib/message-quote.d.ts.map +0 -1
  353. package/lib/message-quote.js +0 -91
  354. package/lib/message-quote.js.map +0 -1
  355. package/lib/message.d.ts.map +0 -1
  356. package/lib/message.js.map +0 -1
  357. package/lib/models/system-log.d.ts.map +0 -1
  358. package/lib/models/system-log.js.map +0 -1
  359. package/lib/models/user.d.ts.map +0 -1
  360. package/lib/models/user.js.map +0 -1
  361. package/lib/notice.d.ts.map +0 -1
  362. package/lib/notice.js.map +0 -1
  363. package/lib/plugin.d.ts.map +0 -1
  364. package/lib/plugin.js.map +0 -1
  365. package/lib/prompt.d.ts.map +0 -1
  366. package/lib/prompt.js.map +0 -1
  367. package/lib/request.d.ts.map +0 -1
  368. package/lib/request.js.map +0 -1
  369. package/lib/scheduler/scheduler.d.ts +0 -49
  370. package/lib/scheduler/scheduler.d.ts.map +0 -1
  371. package/lib/scheduler/scheduler.js +0 -352
  372. package/lib/scheduler/scheduler.js.map +0 -1
  373. package/lib/scheduler/types.d.ts +0 -71
  374. package/lib/scheduler/types.d.ts.map +0 -1
  375. package/lib/scheduler/types.js +0 -8
  376. package/lib/scheduler/types.js.map +0 -1
  377. package/lib/tool-zod.d.ts.map +0 -1
  378. package/lib/tool-zod.js.map +0 -1
  379. package/lib/types-generator.d.ts +0 -6
  380. package/lib/types-generator.d.ts.map +0 -1
  381. package/lib/types-generator.js +0 -72
  382. package/lib/types-generator.js.map +0 -1
  383. package/lib/types.d.ts.map +0 -1
  384. package/lib/types.js.map +0 -1
  385. package/lib/utils.d.ts.map +0 -1
  386. package/lib/utils.js.map +0 -1
package/lib/adapter.js CHANGED
@@ -1,9 +1,16 @@
1
+ import { assertOutbound, DEFAULT_ENDPOINT_CAPABILITIES, hasInbound, } from "./endpoint-capabilities.js";
2
+ import { endpointControlOf } from "@zhin.js/adapter";
3
+ import { connectEndpointInstance, disconnectEndpointInstance } from "./built/connect-endpoint-instance.js";
1
4
  import { EventEmitter } from "node:events";
2
5
  import { getOutboundReplyStore } from "./built/dispatcher.js";
3
- import { coerceHtmlSegmentsToText } from "./built/html-segment-fallback.js";
6
+ import { DEFAULT_OUTBOUND_RICH_SEGMENT_POLICY, resolveRichSegments, } from "./built/rich-segments/index.js";
7
+ import { DEFAULT_INTERACTIVE_POLICY, collectKeyboardFallbackMaps, keyboardFallbackStore, resolveKeyboardSegments, } from "./built/interactive-segments/index.js";
8
+ import { DEFAULT_AI_OUTBOUND_CAPABILITIES, } from "./built/ai-outbound/index.js";
9
+ import { createRichSegmentRenderContext } from "./built/rich-segments/capabilities.js";
10
+ import { collectOutboundMediaKinds } from "./built/outbound-media-utils.js";
4
11
  import { segment } from "./utils.js";
5
- import { runInboundMessage } from "./built/inbound-runner.js";
6
- import { formatCompact, truncatePreview } from '@zhin.js/logger';
12
+ import { InboundMessagePipeline } from "./built/inbound-pipeline.js";
13
+ import { formatCompact, truncatePreview, formatContentChainLog, CONTENT_CHAIN_STAGE } from '@zhin.js/logger';
7
14
  /**
8
15
  * Adapter类:适配器抽象,管理多平台Bot实例。
9
16
  * 负责根据配置启动/关闭各平台机器人,统一异常处理。
@@ -14,8 +21,21 @@ export class Adapter extends EventEmitter {
14
21
  plugin;
15
22
  name;
16
23
  config;
17
- /** 当前适配器下所有Bot实例,key为bot名称 */
18
- bots = new Map();
24
+ endpoints = new Map();
25
+ recallMessageHandler;
26
+ /** Adapter 支持的能力上限(子类覆盖) */
27
+ static capabilities = DEFAULT_ENDPOINT_CAPABILITIES;
28
+ /** 出站富媒体段渲染策略(子类 override static) */
29
+ static outboundRichSegmentPolicy = DEFAULT_OUTBOUND_RICH_SEGMENT_POLICY;
30
+ /** 交互段出站策略:native 保留按钮段,text 降级为编号文本 */
31
+ static interactivePolicy = DEFAULT_INTERACTIVE_POLICY;
32
+ /** AI 结构化出站能力声明(mentions / richSegments / interactive) */
33
+ static aiOutboundCapabilities = DEFAULT_AI_OUTBOUND_CAPABILITIES;
34
+ /** 平台特有 extensions schema + 解析(对齐各 SDK 文档子集) */
35
+ static aiOutboundExtensions;
36
+ getInteractivePolicy() {
37
+ return this.constructor.interactivePolicy;
38
+ }
19
39
  /** 入站消息并发计数 */
20
40
  #pendingMessages = 0;
21
41
  /** 并发上限,0 表示不限制(默认) */
@@ -35,61 +55,54 @@ export class Adapter extends EventEmitter {
35
55
  return this.#pendingMessages;
36
56
  }
37
57
  /**
38
- * 构造函数
58
+ * 创建一个适配器运行实例。
59
+ * @param plugin 拥有该适配器的插件实例
39
60
  * @param name 适配器名称(如 'process'、'qq' 等)
40
- * @param botFactory Bot工厂函数或构造器
61
+ * @param config Endpoint 配置列表
41
62
  */
42
63
  constructor(plugin, name, config) {
43
64
  super();
44
65
  this.plugin = plugin;
45
66
  this.name = name;
46
67
  this.config = config;
47
- this.on('call.recallMessage', async (bot_id, id) => {
48
- const bot = this.bots.get(bot_id);
49
- if (!bot)
50
- throw new Error(`Bot ${bot_id} not found`);
51
- this.logger.debug(formatCompact({ recall: id, bot: bot_id }));
52
- await bot.$recallMessage(id);
68
+ this.recallMessageHandler = (endpoint_id, id) => this.recallEndpointMessage(endpoint_id, id);
69
+ this.on('call.recallMessage', this.recallMessageHandler);
70
+ this.inboundPipeline = new InboundMessagePipeline({
71
+ getPlugin: () => this.plugin,
72
+ logger: this.logger,
73
+ getMaxConcurrentMessages: () => this.maxConcurrentMessages,
74
+ getPendingMessages: () => this.#pendingMessages,
75
+ decrementPending: () => {
76
+ // stop() may zero the counter while in-flight receives still finish;
77
+ // never let the budget go negative.
78
+ this.#pendingMessages = Math.max(0, this.#pendingMessages - 1);
79
+ },
53
80
  });
54
81
  }
82
+ /** 入站消息管线(替代 emit override 的隐式管线) */
83
+ inboundPipeline;
55
84
  /**
56
- * 重写 emit:拦截 message.receive 事件,按架构规定的入站流程处理
57
- * 入站消息链:adapter.emit → dispatcher.dispatch → plugin.dispatch('message.receive') → adapter observers
58
- *
59
- * 以属性 + `EventEmitter.prototype.emit` 调用满足 Node @types 25 对泛型 `emit` 的可赋值检查。
85
+ * 重写 emit:拦截 message.receive/notice.receive/request.receive 事件,
86
+ * 将入站处理委托给 InboundMessagePipeline。
60
87
  */
61
88
  emit = ((event, ...args) => {
89
+ if (event === 'notice.receive' || event === 'request.receive') {
90
+ return this.inboundPipeline.bridgeNoticeOrRequest(event, args, () => EventEmitter.prototype.emit.call(this, event, ...args));
91
+ }
62
92
  if (event !== 'message.receive') {
63
93
  return EventEmitter.prototype.emit.call(this, event, ...args);
64
94
  }
65
95
  const message = args[0];
66
- this.logger.info(formatCompact({
67
- recv: `${message.$channel.type}(${message.$channel.id})`,
68
- bot: message.$bot,
69
- preview: truncatePreview(segment.raw(message.$content)),
70
- ...(message.$quote_id ? { quote_id: message.$quote_id } : {}),
71
- }));
72
- // 背压控制:limit > 0 时启用,超出并发上限丢弃消息并告警
73
- const limit = this.maxConcurrentMessages;
74
- if (limit > 0 && this.#pendingMessages >= limit) {
75
- this.logger.warn(formatCompact({ drop: 'concurrency', limit }));
96
+ // 背压控制:同步返回 false 表示丢弃
97
+ if (this.inboundPipeline.shouldDropDueToBackpressure()) {
98
+ this.logger.warn(formatCompact({ op: 'backpressure_drop', limit: this.maxConcurrentMessages }));
76
99
  return false;
77
100
  }
101
+ // 同步计数,保证背压判断的准确性
78
102
  this.#pendingMessages++;
79
- // 异步执行入站消息处理链
80
- const processing = async () => {
81
- await runInboundMessage({
82
- plugin: this.plugin,
83
- message,
84
- emitAdapterObservers: () => {
85
- EventEmitter.prototype.emit.call(this, event, ...args);
86
- },
87
- });
88
- };
89
- processing().catch((e) => {
90
- this.logger.warn(`message.receive handling error: ${e instanceof Error ? e.message : String(e)}`);
91
- }).finally(() => {
92
- this.#pendingMessages--;
103
+ // 异步入站管线(middleware → dispatcher → 生命周期 → 观察者)
104
+ this.inboundPipeline.receive(message, () => {
105
+ EventEmitter.prototype.emit.call(this, event, ...args);
93
106
  });
94
107
  return true;
95
108
  });
@@ -101,6 +114,28 @@ export class Adapter extends EventEmitter {
101
114
  binding(plugin) {
102
115
  this.plugin = plugin;
103
116
  }
117
+ /**
118
+ * 同步等待入站管线结束(middleware → dispatcher → 生命周期 → 观察者)。
119
+ * 用于 QQ 等需在被动回复完成后再 ack 交互的平台事件。
120
+ */
121
+ async receiveMessageAwait(message) {
122
+ if (this.inboundPipeline.shouldDropDueToBackpressure()) {
123
+ this.logger.warn(formatCompact({ drop: 'concurrency', limit: this.maxConcurrentMessages }));
124
+ return false;
125
+ }
126
+ this.#pendingMessages++;
127
+ try {
128
+ await this.inboundPipeline.receive(message, () => {
129
+ EventEmitter.prototype.emit.call(this, 'message.receive', message);
130
+ });
131
+ return true;
132
+ }
133
+ finally {
134
+ // Inbound pipeline errors must not leak the concurrency budget; the
135
+ // non-await path uses InboundMessagePipeline.decrementPending in finally.
136
+ this.#pendingMessages = Math.max(0, this.#pendingMessages - 1);
137
+ }
138
+ }
104
139
  /**
105
140
  * 出站富媒体能力(Publisher 按此过滤/降级;各 adapter 可覆盖)。
106
141
  */
@@ -113,29 +148,72 @@ export class Adapter extends EventEmitter {
113
148
  maxAttachmentBytes: 26_214_400,
114
149
  };
115
150
  }
151
+ getOutboundRichSegmentPolicy() {
152
+ return this.constructor.outboundRichSegmentPolicy;
153
+ }
154
+ /**
155
+ * 出站两阶段:
156
+ * 1. resolveRichSegments — 语义段 → 标准 IM 段(image/audio/text)
157
+ * 2. Endpoint materializeOutboundMedia — base64/本地路径 → 平台 URL(各 adapter 可选)
158
+ * @see docs/essentials/rich-segment-adapters.md
159
+ */
116
160
  async renderSendMessage(options) {
161
+ if (options.content != null) {
162
+ options = {
163
+ ...options,
164
+ content: await resolveRichSegments(options.content, this.getOutboundRichSegmentPolicy(), createRichSegmentRenderContext({
165
+ getConfig: () => {
166
+ const cfg = this.plugin.root.inject('config')?.getPrimary();
167
+ return cfg;
168
+ },
169
+ warn: (msg) => this.logger.warn(msg),
170
+ logContentChain: (fields) => {
171
+ this.logger.debug(formatContentChainLog({ ...fields, adapter: this.name }));
172
+ },
173
+ })),
174
+ };
175
+ // 'text' 策略端点:keyboard 即将降级为编号文本,先把有效 fallback
176
+ // 映射写入中央存储(频道键与入站回跳解析一致),供数字回跳路由。
177
+ if (this.getInteractivePolicy() === 'text') {
178
+ const channelKey = `${this.name}-${options.endpoint}-${options.type}:${options.id}`;
179
+ for (const map of collectKeyboardFallbackMaps(options.content)) {
180
+ keyboardFallbackStore.remember(channelKey, map);
181
+ }
182
+ }
183
+ options = {
184
+ ...options,
185
+ content: resolveKeyboardSegments(options.content, this.getInteractivePolicy()),
186
+ };
187
+ const mediaKinds = collectOutboundMediaKinds(options.content);
188
+ if (mediaKinds.length > 0) {
189
+ this.logger.debug(formatContentChainLog({
190
+ stage: CONTENT_CHAIN_STAGE.OUTBOUND,
191
+ adapter: this.name,
192
+ endpoint: options.endpoint,
193
+ media: mediaKinds.join(','),
194
+ }));
195
+ }
196
+ }
117
197
  const fns = this.plugin.root.listeners('before.sendMessage');
118
198
  for (const fn of fns) {
119
199
  const result = await fn(options);
120
200
  if (result)
121
201
  options = result;
122
202
  }
123
- if (options.content != null) {
124
- options = { ...options, content: coerceHtmlSegmentsToText(options.content) };
125
- }
126
203
  return options;
127
204
  }
128
205
  async sendMessage(options) {
129
206
  options = await this.renderSendMessage(options);
130
- const bot = this.bots.get(options.bot);
131
- if (!bot)
132
- throw new Error(`Bot ${options.bot} not found`);
133
- this.logger.info(formatCompact({
207
+ const endpoint = this.endpoints.get(options.endpoint);
208
+ if (!endpoint)
209
+ throw new Error(`Endpoint ${options.endpoint} not found`);
210
+ assertOutbound(endpoint);
211
+ this.logger.debug(formatCompact({
134
212
  send: `${options.type}(${options.id})`,
135
- bot: options.bot,
213
+ endpoint: options.endpoint,
136
214
  preview: truncatePreview(segment.raw(options.content)),
137
215
  }));
138
- const messageId = await bot.$sendMessage(options);
216
+ const messageId = await endpoint.$sendMessage(options);
139
217
  const replyStore = getOutboundReplyStore();
140
218
  this.plugin.root.dispatch('message.send', {
141
219
  adapter: this.name,
@@ -146,7 +224,81 @@ export class Adapter extends EventEmitter {
146
224
  });
147
225
  return messageId;
148
226
  }
227
+ /**
228
+ * `call.recallMessage` 事件链(prompt.ts 超时撤回等)的统一出口:
229
+ * 经 canonical `EndpointControl` 端口撤回。
230
+ */
231
+ async recallEndpointMessage(endpointKey, messageId) {
232
+ const endpoint = this.endpoints.get(endpointKey);
233
+ if (!endpoint)
234
+ throw new Error(`Endpoint ${endpointKey} not found`);
235
+ assertOutbound(endpoint);
236
+ const control = endpointControlOf(endpoint);
237
+ if (!control?.recall) {
238
+ throw new Error(`Endpoint ${endpointKey} does not support recall`);
239
+ }
240
+ this.logger.debug(formatCompact({ op: 'recall_message', msgId: messageId, endpoint: endpointKey }));
241
+ await control.recall({
242
+ conversation: {
243
+ endpoint: { id: endpointKey, adapter: String(this.name) },
244
+ kind: 'private',
245
+ id: endpointKey,
246
+ },
247
+ id: messageId,
248
+ });
249
+ }
250
+ /**
251
+ * 编辑已发送的消息。
252
+ * - 如果 Endpoint 的 control 端口实现了 edit,调用平台编辑 API
253
+ * - 否则 fallback 到发送新消息
254
+ * @returns 消息 ID(编辑时返回原 ID,fallback 时返回新消息 ID)
255
+ */
256
+ async editMessage(options) {
257
+ const endpoint = this.endpoints.get(options.endpoint);
258
+ if (!endpoint)
259
+ throw new Error(`Endpoint ${options.endpoint} not found`);
260
+ assertOutbound(endpoint);
261
+ const control = endpointControlOf(endpoint);
262
+ if (control?.edit) {
263
+ const rendered = await this.renderSendMessage({
264
+ context: options.context,
265
+ endpoint: options.endpoint,
266
+ id: options.id,
267
+ type: options.type,
268
+ content: options.content,
269
+ });
270
+ await control.edit({
271
+ conversation: {
272
+ endpoint: { id: options.endpoint, adapter: String(this.name) },
273
+ kind: options.type === 'group' ? 'group' : 'private',
274
+ id: options.id,
275
+ },
276
+ id: options.messageId,
277
+ }, rendered.content);
278
+ this.logger.debug(formatCompact({
279
+ edit: `${options.type}(${options.id})`,
280
+ endpoint: options.endpoint,
281
+ messageId: options.messageId,
282
+ }));
283
+ return options.messageId;
284
+ }
285
+ this.logger.debug(formatCompact({
286
+ editFallback: 'sendMessage',
287
+ endpoint: options.endpoint,
288
+ reason: 'control.edit not implemented',
289
+ }));
290
+ return this.sendMessage({
291
+ context: options.context,
292
+ endpoint: options.endpoint,
293
+ id: options.id,
294
+ type: options.type,
295
+ content: options.content,
296
+ });
297
+ }
149
298
  async start() {
299
+ if (this.endpoints.size > 0) {
300
+ await this.stop();
301
+ }
150
302
  const rootAdapters = this.plugin.root.adapters;
151
303
  if (!rootAdapters.some((n) => String(n) === String(this.name))) {
152
304
  rootAdapters.push(this.name);
@@ -154,31 +306,38 @@ export class Adapter extends EventEmitter {
154
306
  if (!this.config?.length)
155
307
  return;
156
308
  for (const config of this.config) {
157
- const bot = this.createBot(config);
158
- await bot.$connect();
159
- this.logger.debug(formatCompact({ connect: bot.$id, adapter: this.name }));
160
- this.bots.set(bot.$id, bot);
309
+ const endpoint = await connectEndpointInstance({
310
+ plugin: this.plugin,
311
+ adapter: this,
312
+ config: config,
313
+ });
314
+ this.logger.debug(formatCompact({ connect: endpoint.$id, adapter: this.name }));
315
+ this.endpoints.set(endpoint.$id, endpoint);
161
316
  }
162
317
  this.logger.debug(formatCompact({ adapter: this.name }));
163
318
  }
164
319
  /**
165
- * 停止适配器,断开并移除所有Bot实例
166
- * @param plugin 所属插件实例
320
+ * 停止适配器,断开并移除所有 Endpoint 实例
167
321
  */
168
322
  async stop() {
169
323
  const errors = [];
170
- for (const [id, bot] of this.bots) {
324
+ for (const [id, endpoint] of this.endpoints) {
171
325
  try {
172
- await bot.$disconnect();
326
+ if (hasInbound(endpoint)) {
327
+ await disconnectEndpointInstance(this.plugin, this, endpoint);
328
+ }
173
329
  this.logger.debug(formatCompact({ disconnect: id, adapter: this.name }));
174
330
  }
175
331
  catch (error) {
176
332
  errors.push(error instanceof Error ? error : new Error(String(error)));
177
- this.logger.error(`bot ${id} of adapter ${this.name} disconnect failed:`, error);
333
+ this.logger.error(`endpoint ${id} of adapter ${this.name} disconnect failed:`, error);
178
334
  }
179
335
  }
180
336
  // 无论是否有错误,始终完成清理
181
- this.bots.clear();
337
+ this.endpoints.clear();
338
+ // Drop in-flight concurrency counter so a subsequent start() does not
339
+ // inherit a stale backpressure budget from the previous generation.
340
+ this.#pendingMessages = 0;
182
341
  // 从 adapters 数组中移除(可能因重复 start 出现多条同名,需全部删掉)
183
342
  const rootAdapters = this.plugin.root.adapters;
184
343
  for (let i = rootAdapters.length - 1; i >= 0; i--) {
@@ -187,9 +346,11 @@ export class Adapter extends EventEmitter {
187
346
  }
188
347
  // 移除所有事件监听器
189
348
  this.removeAllListeners();
349
+ this.recallMessageHandler = (endpoint_id, id) => this.recallEndpointMessage(endpoint_id, id);
350
+ this.on('call.recallMessage', this.recallMessageHandler);
190
351
  this.logger.debug(formatCompact({ stop: this.name }));
191
352
  if (errors.length) {
192
- throw new AggregateError(errors, `adapter ${this.name}: ${errors.length} bot(s) failed to disconnect`);
353
+ throw new AggregateError(errors, `adapter ${this.name}: ${errors.length} endpoint(s) failed to disconnect`);
193
354
  }
194
355
  }
195
356
  }
@@ -214,4 +375,3 @@ export class Adapter extends EventEmitter {
214
375
  }
215
376
  Adapter.register = register;
216
377
  })(Adapter || (Adapter = {}));
217
- //# sourceMappingURL=adapter.js.map
@@ -1,5 +1,10 @@
1
- import { Adapter, Plugin, Bot, SendOptions, Message } from "@zhin.js/core";
2
- export declare class ProcessBot implements Bot<{
1
+ import { Adapter } from "../adapter.js";
2
+ import { Plugin } from "../plugin.js";
3
+ import { Endpoint } from "../endpoint.js";
4
+ import { Message } from "../message.js";
5
+ import type { SendOptions } from "../types.js";
6
+ import type { OutboundRichSegmentPolicy } from "./rich-segments/types.js";
7
+ export declare class ProcessEndpoint implements Endpoint<{
3
8
  owner?: string;
4
9
  }, {
5
10
  content: string;
@@ -26,18 +31,28 @@ export declare class ProcessBot implements Bot<{
26
31
  content: string;
27
32
  ts: number;
28
33
  }>;
34
+ get control(): {
35
+ recall: (message: {
36
+ id: string;
37
+ }) => Promise<void>;
38
+ };
29
39
  $recallMessage(id: string): Promise<void>;
30
40
  $sendMessage(options: SendOptions): Promise<string>;
31
41
  $connect(): Promise<void>;
32
42
  $disconnect(): Promise<void>;
33
43
  }
34
- export declare class ProcessAdapter extends Adapter<ProcessBot> {
44
+ export declare class ProcessAdapter extends Adapter<ProcessEndpoint> {
45
+ static readonly capabilities: readonly ["inbound", "outbound"];
46
+ static outboundRichSegmentPolicy: OutboundRichSegmentPolicy;
35
47
  constructor(plugin: Plugin);
36
- createBot(config: Adapter.BotConfig<ProcessBot>): ProcessBot;
48
+ /**
49
+ * process 出站由 $sendMessage 写入 stdout;父类 INFO preview 会与终端输出重复,故仅 debug 元数据。
50
+ */
51
+ sendMessage(options: SendOptions): Promise<string>;
52
+ createEndpoint(config: Adapter.EndpointConfig<ProcessEndpoint>): ProcessEndpoint;
37
53
  }
38
54
  declare module '../adapter.js' {
39
55
  interface Adapters {
40
56
  process: ProcessAdapter;
41
57
  }
42
58
  }
43
- //# sourceMappingURL=adapter-process.d.ts.map
@@ -1,6 +1,12 @@
1
- import { Adapter, Message } from "@zhin.js/core";
1
+ import { formatCompact } from "@zhin.js/logger";
2
+ import { Adapter } from "../adapter.js";
3
+ import { Message } from "../message.js";
4
+ import { segment } from "../utils.js";
5
+ import { assertOutbound } from "../endpoint-capabilities.js";
6
+ import { getOutboundReplyStore } from "./dispatcher.js";
2
7
  import { bindStdin, runtimePid, runtimeUser } from "./runtime-io.js";
3
- export class ProcessBot {
8
+ import { interpretOriginQrcodeForProcess } from "./rich-segments/qrcode-segment.js";
9
+ export class ProcessEndpoint {
4
10
  adapter;
5
11
  $config;
6
12
  $id = runtimePid();
@@ -28,7 +34,7 @@ export class ProcessBot {
28
34
  const base = {
29
35
  $id: `${event.ts}`,
30
36
  $adapter: 'process',
31
- $bot: runtimePid(),
37
+ $endpoint: runtimePid(),
32
38
  $sender: {
33
39
  id: runtimeUser(),
34
40
  name: runtimeUser(),
@@ -47,7 +53,7 @@ export class ProcessBot {
47
53
  $reply: async (content) => {
48
54
  return await this.adapter.sendMessage({
49
55
  context: 'process',
50
- bot: base.$bot,
56
+ endpoint: base.$endpoint,
51
57
  content,
52
58
  id: base.$sender.id,
53
59
  type: base.$channel.type,
@@ -56,9 +62,21 @@ export class ProcessBot {
56
62
  };
57
63
  return Message.from(event, base);
58
64
  }
65
+ get control() {
66
+ return {
67
+ recall: async (message) => this.$recallMessage(message.id),
68
+ };
69
+ }
59
70
  async $recallMessage(id) {
60
71
  }
61
72
  async $sendMessage(options) {
73
+ const content = await interpretOriginQrcodeForProcess(options.content ?? '');
74
+ if (content != null) {
75
+ const preview = segment.raw(content);
76
+ if (preview) {
77
+ process.stdout.write(`${preview}\n`);
78
+ }
79
+ }
62
80
  return `${Date.now()}`;
63
81
  }
64
82
  async $connect() {
@@ -71,11 +89,40 @@ export class ProcessBot {
71
89
  }
72
90
  }
73
91
  export class ProcessAdapter extends Adapter {
92
+ static capabilities = ['inbound', 'outbound'];
93
+ static outboundRichSegmentPolicy = {
94
+ qrcode: 'origin',
95
+ html: 'text',
96
+ markdown: 'text',
97
+ };
74
98
  constructor(plugin) {
75
99
  super(plugin, 'process', [{ owner: runtimePid() }]);
76
100
  }
77
- createBot(config) {
78
- return new ProcessBot(this, config);
101
+ /**
102
+ * process 出站由 $sendMessage 写入 stdout;父类 INFO preview 会与终端输出重复,故仅 debug 元数据。
103
+ */
104
+ async sendMessage(options) {
105
+ options = await this.renderSendMessage(options);
106
+ const endpoint = this.endpoints.get(options.endpoint);
107
+ if (!endpoint)
108
+ throw new Error(`Endpoint ${options.endpoint} not found`);
109
+ assertOutbound(endpoint);
110
+ this.logger.debug(formatCompact({
111
+ send: `${options.type}(${options.id})`,
112
+ endpoint: options.endpoint,
113
+ }));
114
+ const messageId = await endpoint.$sendMessage(options);
115
+ const replyStore = getOutboundReplyStore();
116
+ this.plugin.root.dispatch('message.send', {
117
+ adapter: this.name,
118
+ options,
119
+ messageId,
120
+ replySource: replyStore?.source,
121
+ replyMessage: replyStore?.message,
122
+ });
123
+ return messageId;
124
+ }
125
+ createEndpoint(config) {
126
+ return new ProcessEndpoint(this, config);
79
127
  }
80
128
  }
81
- //# sourceMappingURL=adapter-process.js.map
@@ -48,7 +48,7 @@ declare module '../plugin.js' {
48
48
  export declare class AgentPresetFeature extends Feature<AgentPreset> {
49
49
  #private;
50
50
  readonly name: "agentPreset";
51
- readonly icon = "Bot";
51
+ readonly icon = "Endpoint";
52
52
  readonly desc = "Agent \u9884\u8BBE";
53
53
  readonly byName: Map<string, AgentPreset>;
54
54
  add(preset: AgentPreset, pluginName: string): () => void;
@@ -62,4 +62,3 @@ export declare class AgentPresetFeature extends Feature<AgentPreset> {
62
62
  }): AgentPreset[];
63
63
  toJSON(pluginName?: string): FeatureJSON;
64
64
  }
65
- //# sourceMappingURL=agent-preset.d.ts.map
@@ -12,7 +12,7 @@
12
12
  import { Feature } from '@zhin.js/kernel';
13
13
  export class AgentPresetFeature extends Feature {
14
14
  name = 'agentPreset';
15
- icon = 'Bot';
15
+ icon = 'Endpoint';
16
16
  desc = 'Agent 预设';
17
17
  byName = new Map();
18
18
  add(preset, pluginName) {
@@ -77,4 +77,3 @@ export class AgentPresetFeature extends Feature {
77
77
  };
78
78
  }
79
79
  }
80
- //# sourceMappingURL=agent-preset.js.map
@@ -0,0 +1,36 @@
1
+ /**
2
+ * AI Access Gate — 控制 LLM 回复路径是否对当前会话开放(平台 AIGC 合规等)
3
+ */
4
+ import type { Message } from '../message.js';
5
+ export type AIAccessMode = 'open' | 'closed' | 'whitelist';
6
+ /** Endpoint 或全局 ai.access 配置块 */
7
+ export interface AIAccessScopeConfig {
8
+ mode?: AIAccessMode;
9
+ /** 允许触发 AI 的 sender.id */
10
+ users?: string[];
11
+ /** 允许触发 AI 的 group/channel id */
12
+ groups?: string[];
13
+ /** 私聊拒绝时的回复文案 */
14
+ denyMessage?: string;
15
+ }
16
+ /** 全局 ai.access 配置(与 AIAccessScopeConfig 同形) */
17
+ export type AIAccessConfig = AIAccessScopeConfig;
18
+ export interface ResolvedAIAccessConfig {
19
+ mode: AIAccessMode;
20
+ users: string[];
21
+ groups: string[];
22
+ denyMessage: string;
23
+ }
24
+ export interface AIAccessResult {
25
+ allowed: boolean;
26
+ reason: string;
27
+ /** 私聊拒绝时返回;群/频道拒绝为 undefined(静默) */
28
+ replyMessage?: string;
29
+ }
30
+ export declare const DEFAULT_AI_ACCESS_DENY_MESSAGE = "\u5F53\u524D\u4F1A\u8BDD\u672A\u5F00\u653E AI \u529F\u80FD\u3002";
31
+ export declare function resolveAIAccessConfig(global: AIAccessConfig | undefined, endpointScope?: AIAccessScopeConfig): ResolvedAIAccessConfig;
32
+ /**
33
+ * 判定当前消息是否允许进入 AI Handler(LLM 回复路径)。
34
+ * 不影响命令、游戏等其它 Dispatcher 分支。
35
+ */
36
+ export declare function checkAIAccess(message: Message<any>, globalConfig: AIAccessConfig | undefined, endpointScope?: AIAccessScopeConfig): AIAccessResult;
@@ -0,0 +1,46 @@
1
+ export const DEFAULT_AI_ACCESS_DENY_MESSAGE = '当前会话未开放 AI 功能。';
2
+ const DEFAULT_MODE = 'open';
3
+ export function resolveAIAccessConfig(global, endpointScope) {
4
+ const base = global ?? {};
5
+ const endpoint = endpointScope ?? {};
6
+ return {
7
+ mode: endpoint.mode ?? base.mode ?? DEFAULT_MODE,
8
+ users: endpoint.users ?? base.users ?? [],
9
+ groups: endpoint.groups ?? base.groups ?? [],
10
+ denyMessage: endpoint.denyMessage ?? base.denyMessage ?? DEFAULT_AI_ACCESS_DENY_MESSAGE,
11
+ };
12
+ }
13
+ function isWhitelisted(message, config) {
14
+ const userId = String(message.$sender?.id ?? '');
15
+ if (userId && config.users.includes(userId))
16
+ return true;
17
+ const scope = message.$channel?.type;
18
+ if (scope === 'group' || scope === 'channel') {
19
+ const channelId = String(message.$channel?.id ?? '');
20
+ if (channelId && config.groups.includes(channelId))
21
+ return true;
22
+ }
23
+ return false;
24
+ }
25
+ function denyResult(message, config, reason) {
26
+ const scope = message.$channel?.type;
27
+ const replyMessage = scope === 'private' ? config.denyMessage : undefined;
28
+ return { allowed: false, reason, replyMessage };
29
+ }
30
+ /**
31
+ * 判定当前消息是否允许进入 AI Handler(LLM 回复路径)。
32
+ * 不影响命令、游戏等其它 Dispatcher 分支。
33
+ */
34
+ export function checkAIAccess(message, globalConfig, endpointScope) {
35
+ const config = resolveAIAccessConfig(globalConfig, endpointScope);
36
+ if (config.mode === 'open') {
37
+ return { allowed: true, reason: 'mode: open' };
38
+ }
39
+ if (config.mode === 'closed') {
40
+ return denyResult(message, config, 'mode: closed');
41
+ }
42
+ if (isWhitelisted(message, config)) {
43
+ return { allowed: true, reason: 'whitelist: matched' };
44
+ }
45
+ return denyResult(message, config, 'whitelist: not matched');
46
+ }
@@ -0,0 +1,3 @@
1
+ import { type AiOutboundCapabilities, type AiOutboundExtensionDefinition } from './types.js';
2
+ export declare function getAdapterAiOutboundCapabilities(adapterInstance: object): AiOutboundCapabilities;
3
+ export declare function getAdapterAiOutboundExtensions(adapterInstance: object): readonly AiOutboundExtensionDefinition[];
@@ -0,0 +1,9 @@
1
+ import { DEFAULT_AI_OUTBOUND_CAPABILITIES, } from './types.js';
2
+ export function getAdapterAiOutboundCapabilities(adapterInstance) {
3
+ const ctor = adapterInstance.constructor;
4
+ return ctor.aiOutboundCapabilities ?? DEFAULT_AI_OUTBOUND_CAPABILITIES;
5
+ }
6
+ export function getAdapterAiOutboundExtensions(adapterInstance) {
7
+ const ctor = adapterInstance.constructor;
8
+ return ctor.aiOutboundExtensions ?? [];
9
+ }
@@ -0,0 +1,2 @@
1
+ import type { AiOutboundExtensionDefinition } from '../types.js';
2
+ export declare const ONEBOT_KEYBOARD_AI_OUTBOUND_EXTENSION: AiOutboundExtensionDefinition;