@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
@@ -6,34 +6,77 @@
6
6
  * 待办未消费前会一直保留,刷新页面后仍可继续消费。
7
7
  *
8
8
  * 事件:
9
- * bot.login.pending — 有新待办时触发,payload: PendingLoginTask
9
+ * endpoint.login.pending — 有新待办时触发,payload: PendingLoginTask
10
+ * endpoint.login.expired — 超时自动取消时触发,payload: PendingLoginTask
10
11
  */
12
+ /** 默认 5 分钟;扫码/滑块长期挂起会泄漏 Promise 与 Map 条目 */
13
+ export const DEFAULT_LOGIN_ASSIST_TIMEOUT_MS = 5 * 60 * 1000;
11
14
  // ============================================================================
12
15
  // LoginAssist 服务
13
16
  // ============================================================================
14
17
  export class LoginAssist {
15
- plugin;
18
+ bus;
16
19
  pending = new Map();
20
+ local = new Map();
17
21
  idSeq = 0;
18
- constructor(plugin) {
19
- this.plugin = plugin;
22
+ /** 构造时默认超时;可被 waitForInput options 覆盖 */
23
+ defaultTimeoutMs;
24
+ constructor(bus, options) {
25
+ this.bus = bus ?? null;
26
+ this.defaultTimeoutMs = options?.defaultTimeoutMs ?? DEFAULT_LOGIN_ASSIST_TIMEOUT_MS;
20
27
  }
21
28
  /**
22
- * 生产者:等待用户输入后 resolve。会发出 bot.login.pending 事件,未消费前可被 listPending 拉取(刷新后可继续消费)。
29
+ * Subscribe without requiring a Plugin EventEmitter.
30
+ * Returns unsubscribe.
23
31
  */
24
- waitForInput(adapter, botId, type, payload = {}) {
32
+ subscribe(name, listener) {
33
+ let set = this.local.get(name);
34
+ if (!set) {
35
+ set = new Set();
36
+ this.local.set(name, set);
37
+ }
38
+ set.add(listener);
39
+ return () => {
40
+ set.delete(listener);
41
+ };
42
+ }
43
+ /**
44
+ * 生产者:等待用户输入后 resolve。会发出 endpoint.login.pending 事件,未消费前可被 listPending 拉取(刷新后可继续消费)。
45
+ * 超时后 reject 并 emit `endpoint.login.expired`。
46
+ */
47
+ waitForInput(adapter, endpointKey, type, payload, options) {
25
48
  const id = `login-${Date.now()}-${++this.idSeq}`;
49
+ const timeoutMs = resolveTimeoutMs(options?.timeoutMs, this.defaultTimeoutMs);
50
+ const createdAt = Date.now();
26
51
  const task = {
27
52
  id,
28
53
  adapter,
29
- botId,
54
+ endpointKey,
30
55
  type,
31
56
  payload: { message: payload.message ?? '', ...payload },
32
- createdAt: Date.now(),
57
+ createdAt,
58
+ ...(timeoutMs != null ? { expiresAt: createdAt + timeoutMs } : {}),
33
59
  };
34
60
  const promise = new Promise((resolve, reject) => {
35
- this.pending.set(id, { task, resolve, reject });
36
- this.plugin.emit('bot.login.pending', task);
61
+ const entry = { task, owner: options.owner, resolve, reject };
62
+ if (timeoutMs != null) {
63
+ entry.timer = setTimeout(() => {
64
+ if (!this.pending.has(id))
65
+ return;
66
+ this.pending.delete(id);
67
+ try {
68
+ this.#notify('endpoint.login.expired', task);
69
+ }
70
+ catch {
71
+ /* observer failure must not leave the producer hanging forever */
72
+ }
73
+ reject(new Error(`LoginAssist task timed out after ${timeoutMs}ms`));
74
+ }, timeoutMs);
75
+ // Node: 不阻止进程退出
76
+ entry.timer.unref?.();
77
+ }
78
+ this.pending.set(id, entry);
79
+ this.#notify('endpoint.login.pending', task);
37
80
  });
38
81
  return promise;
39
82
  }
@@ -45,7 +88,10 @@ export class LoginAssist {
45
88
  if (!entry)
46
89
  return false;
47
90
  this.pending.delete(id);
91
+ if (entry.timer)
92
+ clearTimeout(entry.timer);
48
93
  entry.resolve(value);
94
+ this.#notify('endpoint.login.resolved', entry.task);
49
95
  return true;
50
96
  }
51
97
  /**
@@ -56,20 +102,76 @@ export class LoginAssist {
56
102
  if (!entry)
57
103
  return false;
58
104
  this.pending.delete(id);
105
+ if (entry.timer)
106
+ clearTimeout(entry.timer);
59
107
  entry.reject(new Error(reason));
108
+ this.#notify('endpoint.login.resolved', entry.task);
60
109
  return true;
61
110
  }
111
+ /**
112
+ * Cancel pending tasks created by one exact Endpoint instance.
113
+ */
114
+ cancelOwned(owner, reason = 'superseded') {
115
+ let count = 0;
116
+ for (const [id, entry] of [...this.pending]) {
117
+ if (entry.owner !== owner)
118
+ continue;
119
+ this.pending.delete(id);
120
+ if (entry.timer)
121
+ clearTimeout(entry.timer);
122
+ entry.reject(new Error(reason));
123
+ this.#notify('endpoint.login.resolved', entry.task);
124
+ count += 1;
125
+ }
126
+ return count;
127
+ }
62
128
  /**
63
129
  * 列出未消费的待办(供 Web/CLI 展示,刷新后仍可拉取同一列表)。
64
130
  */
65
131
  listPending() {
66
132
  return [...this.pending.values()].map((e) => e.task);
67
133
  }
134
+ hasPending(adapter, endpointKey) {
135
+ if (adapter == null)
136
+ return this.pending.size > 0;
137
+ for (const entry of this.pending.values()) {
138
+ if (entry.task.adapter !== adapter)
139
+ continue;
140
+ if (endpointKey != null && entry.task.endpointKey !== endpointKey)
141
+ continue;
142
+ return true;
143
+ }
144
+ return false;
145
+ }
68
146
  dispose() {
69
147
  for (const [, entry] of this.pending) {
148
+ if (entry.timer)
149
+ clearTimeout(entry.timer);
70
150
  entry.reject(new Error('LoginAssist disposed'));
71
151
  }
72
152
  this.pending.clear();
153
+ this.local.clear();
154
+ }
155
+ #notify(name, task) {
156
+ try {
157
+ this.bus?.emit(name, task);
158
+ }
159
+ catch {
160
+ /* bus observers must not break producer */
161
+ }
162
+ for (const listener of this.local.get(name) ?? []) {
163
+ try {
164
+ listener(task);
165
+ }
166
+ catch {
167
+ /* same */
168
+ }
169
+ }
73
170
  }
74
171
  }
75
- //# sourceMappingURL=login-assist.js.map
172
+ function resolveTimeoutMs(explicit, fallback) {
173
+ const raw = explicit === undefined ? fallback : explicit;
174
+ if (!Number.isFinite(raw) || raw <= 0)
175
+ return undefined;
176
+ return raw;
177
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * IM 运维 / Endpoint 管理斜杠命令:仅 master 或 trusted 可执行。
3
+ */
4
+ import { resolveSenderRoles, type AITriggerConfig } from './ai-trigger.js';
5
+ import type { Message } from '../message.js';
6
+ import type { Plugin } from '../plugin.js';
7
+ export declare const MANAGEMENT_COMMAND_DENIED = "\u26A0\uFE0F \u8BE5\u547D\u4EE4\u4EC5 Endpoint Owner\uFF08master\uFF09\u6216 trusted \u64CD\u4F5C\u5458\u53EF\u7528\u3002";
8
+ /** 运维 / 内省 / Endpoint 管理命令:仅 master 或 trusted 可执行与展示 */
9
+ export declare const MANAGEMENT_OPERATOR_PERMIT: "role(master,trusted)";
10
+ /** Endpoint Owner 私聊专用命令(如 /approve) */
11
+ export declare const OWNER_OPERATOR_PERMIT: "role(master)";
12
+ export declare const OWNER_PRIVATE_PERMITS: readonly ["role(master)", "private(*)"];
13
+ export declare function resolveManagementCommandRoles(message: Message, root: Plugin, triggerConfig?: AITriggerConfig): ReturnType<typeof resolveSenderRoles>['roles'];
14
+ /** 通过返回 null;拒绝返回用户可见提示文案 */
15
+ export declare function rejectUnlessManagementOperator(message: Message, root: Plugin, triggerConfig?: AITriggerConfig): string | null;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * IM 运维 / Endpoint 管理斜杠命令:仅 master 或 trusted 可执行。
3
+ */
4
+ import { mergeAITriggerConfig, resolveSenderRoles, } from './ai-trigger.js';
5
+ import { hasSenderRole } from './roles.js';
6
+ export const MANAGEMENT_COMMAND_DENIED = '⚠️ 该命令仅 Endpoint Owner(master)或 trusted 操作员可用。';
7
+ /** 运维 / 内省 / Endpoint 管理命令:仅 master 或 trusted 可执行与展示 */
8
+ export const MANAGEMENT_OPERATOR_PERMIT = 'role(master,trusted)';
9
+ /** Endpoint Owner 私聊专用命令(如 /approve) */
10
+ export const OWNER_OPERATOR_PERMIT = 'role(master)';
11
+ export const OWNER_PRIVATE_PERMITS = [OWNER_OPERATOR_PERMIT, 'private(*)'];
12
+ export function resolveManagementCommandRoles(message, root, triggerConfig) {
13
+ const cfg = mergeAITriggerConfig(triggerConfig ?? {});
14
+ const adapterInstance = root.inject(message.$adapter);
15
+ const endpointConfig = adapterInstance?.endpoints?.get(message.$endpoint)?.$config;
16
+ return resolveSenderRoles(message, cfg, endpointConfig).roles;
17
+ }
18
+ /** 通过返回 null;拒绝返回用户可见提示文案 */
19
+ export function rejectUnlessManagementOperator(message, root, triggerConfig) {
20
+ const roles = resolveManagementCommandRoles(message, root, triggerConfig);
21
+ if (hasSenderRole(roles, 'trusted')) {
22
+ return null;
23
+ }
24
+ return MANAGEMENT_COMMAND_DENIED;
25
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Message enrich — 入站鉴权快照与合成通讯上下文
3
+ */
4
+ import type { Plugin } from '../plugin.js';
5
+ import { Message, type MessageChannel } from '../message.js';
6
+ import type { Adapters } from '../adapter.js';
7
+ import type { SendContent } from '../types.js';
8
+ import { type SenderRole } from './roles.js';
9
+ /** Agent turn 可挂载在 Message 扩展字段上的元数据 */
10
+ export type AgentTurnMessage = Message<{
11
+ extra?: Record<string, unknown>;
12
+ }>;
13
+ export declare function senderRolesFromMessage(message: Message<any>): readonly SenderRole[];
14
+ /**
15
+ * 入站 enrich:写入 $sender.isMaster / isTrusted 快照(本 turn 只读)
16
+ */
17
+ export declare function enrichMessageForAgent(plugin: Plugin, message: Message<any>): Message<any>;
18
+ export interface SyntheticMessageInput {
19
+ adapter: keyof Adapters | string;
20
+ endpoint: string;
21
+ sender: {
22
+ id: string;
23
+ name?: string;
24
+ role?: string;
25
+ isMaster?: boolean;
26
+ isTrusted?: boolean;
27
+ };
28
+ channel: MessageChannel;
29
+ id?: string;
30
+ reply?: (content: SendContent, quote?: boolean | string) => Promise<string>;
31
+ extra?: Record<string, unknown>;
32
+ }
33
+ /** cron / subagent / mission 等无真实入站时构造最小 Message */
34
+ export declare function createSyntheticMessage(input: SyntheticMessageInput): AgentTurnMessage;
35
+ /** hook context 中的 commMessage 字段(AIHookEvent.context) */
36
+ export declare function commMessageFromHookContext(context: Record<string, unknown>): Message<any> | undefined;
37
+ /** 兼容 tool parameters 上的 contextKey(endpointKey / sceneId / scope 等) */
38
+ export declare function resolveContextKey(message: Message<any>, key: string): unknown;
@@ -0,0 +1,75 @@
1
+ import { Message } from '../message.js';
2
+ import { hasSenderRole } from './roles.js';
3
+ import { resolveSubjectRoles } from './authorization.js';
4
+ function frameworkRolesFromSenderFlags(sender) {
5
+ if (sender.isMaster)
6
+ return ['master'];
7
+ if (sender.isTrusted)
8
+ return ['trusted'];
9
+ return ['user'];
10
+ }
11
+ export function senderRolesFromMessage(message) {
12
+ const sender = message.$sender;
13
+ if (sender.isMaster !== undefined || sender.isTrusted !== undefined) {
14
+ return frameworkRolesFromSenderFlags(sender);
15
+ }
16
+ return ['user'];
17
+ }
18
+ /**
19
+ * 入站 enrich:写入 $sender.isMaster / isTrusted 快照(本 turn 只读)
20
+ */
21
+ export function enrichMessageForAgent(plugin, message) {
22
+ const { roles } = resolveSubjectRoles(plugin.root ?? plugin, message);
23
+ message.$sender.isMaster = hasSenderRole(roles, 'master');
24
+ message.$sender.isTrusted = !message.$sender.isMaster && hasSenderRole(roles, 'trusted');
25
+ return message;
26
+ }
27
+ /** cron / subagent / mission 等无真实入站时构造最小 Message */
28
+ export function createSyntheticMessage(input) {
29
+ const id = input.id ?? `synthetic:${Date.now()}`;
30
+ const reply = input.reply ?? (async () => id);
31
+ return Message.from({ extra: input.extra }, {
32
+ $id: id,
33
+ $adapter: input.adapter,
34
+ $endpoint: input.endpoint,
35
+ $content: [],
36
+ $sender: { ...input.sender },
37
+ $reply: reply,
38
+ $recall: async () => { },
39
+ $channel: input.channel,
40
+ $timestamp: Date.now(),
41
+ $raw: '',
42
+ });
43
+ }
44
+ /** hook context 中的 commMessage 字段(AIHookEvent.context) */
45
+ export function commMessageFromHookContext(context) {
46
+ const raw = context.commMessage;
47
+ if (raw && typeof raw === 'object' && '$sender' in raw) {
48
+ return raw;
49
+ }
50
+ return undefined;
51
+ }
52
+ /** 兼容 tool parameters 上的 contextKey(endpointKey / sceneId / scope 等) */
53
+ export function resolveContextKey(message, key) {
54
+ switch (key) {
55
+ case 'platform':
56
+ return message.$adapter;
57
+ case 'endpointKey':
58
+ return message.$endpoint;
59
+ case 'messageId':
60
+ return message.$id;
61
+ case 'sceneId':
62
+ return message.$channel?.id ?? message.$sender.id;
63
+ case 'senderId':
64
+ return message.$sender.id;
65
+ case 'scope':
66
+ return message.$channel?.type ?? 'private';
67
+ default: {
68
+ if (key in message) {
69
+ return message[key];
70
+ }
71
+ const extra = message.extra;
72
+ return extra?.[key];
73
+ }
74
+ }
75
+ }
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * 核心特性:
9
9
  * - 基于优先级的规则引擎(first-match-wins,类似防火墙规则)
10
- * - 多维匹配:scope / adapter / bot / channel / sender
10
+ * - 多维匹配:scope / adapter / endpoint / channel / sender
11
11
  * - 支持精确匹配、通配符 `*`、正则 `/pattern/`
12
12
  * - 通过 Dispatcher Guardrail 集成,在消息调度第一阶段拦截
13
13
  * - 插件通过 `addFilterRule()` 动态注册规则,卸载时自动清理
@@ -52,8 +52,8 @@ export interface FilterRule {
52
52
  scopes?: FilterScope[];
53
53
  /** 匹配的适配器名称 */
54
54
  adapters?: FilterPattern[];
55
- /** 匹配的 Bot 名称 */
56
- bots?: FilterPattern[];
55
+ /** 匹配的 Endpoint 名称 */
56
+ endpoints?: FilterPattern[];
57
57
  /** 匹配的频道/群/会话 ID */
58
58
  channels?: FilterPattern[];
59
59
  /** 匹配的发送者 ID */
@@ -77,7 +77,7 @@ export interface FilterRuleConfig {
77
77
  enabled?: boolean;
78
78
  scopes?: FilterScope[];
79
79
  adapters?: string[];
80
- bots?: string[];
80
+ endpoints?: string[];
81
81
  channels?: string[];
82
82
  senders?: string[];
83
83
  }
@@ -174,4 +174,3 @@ export declare class MessageFilterFeature extends Feature<FilterRule> {
174
174
  setDefaultFilterPolicy(policy: FilterAction): void;
175
175
  };
176
176
  }
177
- //# sourceMappingURL=message-filter.d.ts.map
@@ -7,13 +7,12 @@
7
7
  *
8
8
  * 核心特性:
9
9
  * - 基于优先级的规则引擎(first-match-wins,类似防火墙规则)
10
- * - 多维匹配:scope / adapter / bot / channel / sender
10
+ * - 多维匹配:scope / adapter / endpoint / channel / sender
11
11
  * - 支持精确匹配、通配符 `*`、正则 `/pattern/`
12
12
  * - 通过 Dispatcher Guardrail 集成,在消息调度第一阶段拦截
13
13
  * - 插件通过 `addFilterRule()` 动态注册规则,卸载时自动清理
14
14
  */
15
15
  import { Feature } from '@zhin.js/kernel';
16
- import { getPlugin } from '../plugin.js';
17
16
  // ============================================================================
18
17
  // 规则工厂
19
18
  // ============================================================================
@@ -144,7 +143,7 @@ export class MessageFilterFeature extends Feature {
144
143
  enabled: r.enabled !== false,
145
144
  scopes: r.scopes,
146
145
  adapters: r.adapters?.map(p => p instanceof RegExp ? p.source : p),
147
- bots: r.bots?.map(p => p instanceof RegExp ? p.source : p),
146
+ endpoints: r.endpoints?.map(p => p instanceof RegExp ? p.source : p),
148
147
  channels: r.channels?.map(p => p instanceof RegExp ? p.source : p),
149
148
  senders: r.senders?.map(p => p instanceof RegExp ? p.source : p),
150
149
  })),
@@ -155,7 +154,7 @@ export class MessageFilterFeature extends Feature {
155
154
  const feature = this;
156
155
  return {
157
156
  addFilterRule(rule) {
158
- const plugin = getPlugin();
157
+ const plugin = this;
159
158
  const dispose = feature.add(rule, plugin.name);
160
159
  plugin.recordFeatureContribution(feature.name, rule.name);
161
160
  plugin.onDispose(dispose);
@@ -195,7 +194,7 @@ export class MessageFilterFeature extends Feature {
195
194
  enabled: rc.enabled,
196
195
  scopes: rc.scopes,
197
196
  adapters: rc.adapters?.map(p => this.#parsePattern(p)),
198
- bots: rc.bots?.map(p => this.#parsePattern(p)),
197
+ endpoints: rc.endpoints?.map(p => this.#parsePattern(p)),
199
198
  channels: rc.channels?.map(p => this.#parsePattern(p)),
200
199
  senders: rc.senders?.map(p => this.#parsePattern(p)),
201
200
  };
@@ -216,7 +215,7 @@ export class MessageFilterFeature extends Feature {
216
215
  if (rule.adapters?.length && !this.#matchAny(rule.adapters, String(message.$adapter))) {
217
216
  return false;
218
217
  }
219
- if (rule.bots?.length && !this.#matchAny(rule.bots, String(message.$bot))) {
218
+ if (rule.endpoints?.length && !this.#matchAny(rule.endpoints, String(message.$endpoint))) {
220
219
  return false;
221
220
  }
222
221
  if (rule.channels?.length && !this.#matchAny(rule.channels, String(message.$channel.id))) {
@@ -238,4 +237,3 @@ export class MessageFilterFeature extends Feature {
238
237
  });
239
238
  }
240
239
  }
241
- //# sourceMappingURL=message-filter.js.map
@@ -0,0 +1,3 @@
1
+ /** 从应用根(ZHIN_PROJECT_ROOT / cwd)解析 optional peer,避免 core 包目录下 dynamic import 失败 */
2
+ export declare function resolveOptionalPeerPackage(packageName: string): string | undefined;
3
+ export declare function importOptionalPeerPackage<T = Record<string, unknown>>(packageName: string): Promise<T>;
@@ -0,0 +1,33 @@
1
+ import { createRequire } from 'node:module';
2
+ import path from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ /** 从应用根(ZHIN_PROJECT_ROOT / cwd)解析 optional peer,避免 core 包目录下 dynamic import 失败 */
5
+ export function resolveOptionalPeerPackage(packageName) {
6
+ const roots = new Set();
7
+ const envRoot = process.env.ZHIN_PROJECT_ROOT?.trim();
8
+ if (envRoot)
9
+ roots.add(path.resolve(envRoot));
10
+ roots.add(process.cwd());
11
+ for (const root of roots) {
12
+ try {
13
+ const req = createRequire(path.join(root, 'package.json'));
14
+ return req.resolve(packageName);
15
+ }
16
+ catch {
17
+ // try next root
18
+ }
19
+ }
20
+ try {
21
+ return createRequire(import.meta.url).resolve(packageName);
22
+ }
23
+ catch {
24
+ return undefined;
25
+ }
26
+ }
27
+ export async function importOptionalPeerPackage(packageName) {
28
+ const resolved = resolveOptionalPeerPackage(packageName);
29
+ if (resolved) {
30
+ return import(pathToFileURL(resolved).href);
31
+ }
32
+ return import(packageName);
33
+ }
@@ -0,0 +1,22 @@
1
+ import type { SendContent } from '../types.js';
2
+ /**
3
+ * 出站两阶段契约(Adapter 实现参考):
4
+ *
5
+ * 1. **resolveRichSegments**(Adapter.renderSendMessage 首步)
6
+ * 语义段(html / tts / qrcode / markdown)→ 标准 IM 段(image / audio / text)
7
+ *
8
+ * 2. **materializeOutboundMedia**(Endpoint.$sendMessage 前,各 adapter 可选)
9
+ * 标准段中的 base64 / 本地路径 → 平台 URL 或上传后的引用
10
+ */
11
+ export interface OutboundMediaUploadContext {
12
+ /** 上传二进制,返回平台可发送的 URL */
13
+ uploadBuffer?(buffer: Buffer, mimeHint?: string): Promise<string>;
14
+ /** 上传本地文件路径 */
15
+ uploadFile?(filePath: string): Promise<string>;
16
+ outboundDir?: string;
17
+ }
18
+ export type OutboundMediaMaterializer = (content: SendContent, ctx: OutboundMediaUploadContext) => Promise<SendContent>;
19
+ /** 契约测试:adapter 须声明 outboundRichSegmentPolicy */
20
+ export declare function assertAdapterDeclaresRichSegmentPolicy(adapterClass: {
21
+ outboundRichSegmentPolicy?: Record<string, string>;
22
+ }): void;
@@ -0,0 +1,10 @@
1
+ /** 契约测试:adapter 须声明 outboundRichSegmentPolicy */
2
+ export function assertAdapterDeclaresRichSegmentPolicy(adapterClass) {
3
+ if (!adapterClass.outboundRichSegmentPolicy) {
4
+ throw new Error('Adapter must declare static outboundRichSegmentPolicy');
5
+ }
6
+ const policy = adapterClass.outboundRichSegmentPolicy;
7
+ if (typeof policy !== 'object' || Object.keys(policy).length === 0) {
8
+ throw new Error('outboundRichSegmentPolicy must be a non-empty object');
9
+ }
10
+ }
@@ -0,0 +1,9 @@
1
+ import type { MessageElement, SendContent } from '../types.js';
2
+ export declare function isRemoteUrl(value: string): boolean;
3
+ /** 从 message 段 data 提取 base64 Buffer(data: URL / base64:// / raw base64) */
4
+ export declare function extractBase64Buffer(data: Record<string, unknown>): Buffer | undefined;
5
+ /** 解析本地文件路径(非 http(s) / base64) */
6
+ export declare function resolveLocalMediaPath(data: Record<string, unknown>): string | undefined;
7
+ export declare function asMessageElements(content: SendContent): MessageElement[];
8
+ export declare function isMediaSegmentType(type: string): boolean;
9
+ export declare function collectOutboundMediaKinds(content: SendContent | undefined): string[];
@@ -0,0 +1,62 @@
1
+ const MEDIA_SEGMENT_TYPES = new Set(['image', 'audio', 'video', 'file']);
2
+ export function isRemoteUrl(value) {
3
+ return /^https?:\/\//i.test(value);
4
+ }
5
+ /** 从 message 段 data 提取 base64 Buffer(data: URL / base64:// / raw base64) */
6
+ export function extractBase64Buffer(data) {
7
+ const url = typeof data.url === 'string' ? data.url : undefined;
8
+ const file = typeof data.file === 'string' ? data.file : undefined;
9
+ const base64 = typeof data.base64 === 'string' ? data.base64 : undefined;
10
+ if (url?.startsWith('base64://')) {
11
+ return Buffer.from(url.slice(9), 'base64');
12
+ }
13
+ if (url && /^data:[^/]+\/[^;]+;base64,/i.test(url)) {
14
+ return Buffer.from(url.replace(/^data:[^/]+\/[^;]+;base64,/, ''), 'base64');
15
+ }
16
+ if (file?.startsWith('base64://')) {
17
+ return Buffer.from(file.slice(9), 'base64');
18
+ }
19
+ if (base64) {
20
+ const raw = base64.startsWith('base64://') ? base64.slice(9) : base64;
21
+ return Buffer.from(raw, 'base64');
22
+ }
23
+ return undefined;
24
+ }
25
+ /** 解析本地文件路径(非 http(s) / base64) */
26
+ export function resolveLocalMediaPath(data) {
27
+ const url = typeof data.url === 'string' ? data.url : undefined;
28
+ const file = typeof data.file === 'string' ? data.file : undefined;
29
+ const candidate = file ?? url;
30
+ if (!candidate || isRemoteUrl(candidate))
31
+ return undefined;
32
+ if (candidate.startsWith('base64://') || /^data:/.test(candidate))
33
+ return undefined;
34
+ if (candidate.startsWith('file://') || candidate.startsWith('/') || !candidate.includes('://')) {
35
+ return candidate;
36
+ }
37
+ return undefined;
38
+ }
39
+ export function asMessageElements(content) {
40
+ if (typeof content === 'string') {
41
+ return [{ type: 'text', data: { text: content } }];
42
+ }
43
+ if (!Array.isArray(content)) {
44
+ return [content];
45
+ }
46
+ return content.map((item) => typeof item === 'string' ? { type: 'text', data: { text: item } } : item);
47
+ }
48
+ export function isMediaSegmentType(type) {
49
+ return MEDIA_SEGMENT_TYPES.has(type);
50
+ }
51
+ export function collectOutboundMediaKinds(content) {
52
+ if (content == null)
53
+ return [];
54
+ const kinds = new Set();
55
+ for (const item of asMessageElements(content)) {
56
+ const t = item?.type;
57
+ if (typeof t === 'string' && isMediaSegmentType(t)) {
58
+ kinds.add(t);
59
+ }
60
+ }
61
+ return [...kinds];
62
+ }
@@ -5,6 +5,7 @@
5
5
  import { Feature, FeatureJSON } from "@zhin.js/kernel";
6
6
  import type { MaybePromise, RegisteredAdapter, AdapterMessage } from "../types.js";
7
7
  import { Message as MessageClass } from "../message.js";
8
+ export type PermissionSubject = MessageClass<AdapterMessage<RegisteredAdapter>>;
8
9
  export type PermissionItem<T extends RegisteredAdapter = RegisteredAdapter> = {
9
10
  name: string | RegExp;
10
11
  check: PermissionChecker<T>;
@@ -31,9 +32,9 @@ export declare class PermissionFeature extends Feature<PermissionItem> {
31
32
  readonly desc = "\u6743\u9650";
32
33
  constructor();
33
34
  /**
34
- * 检查权限
35
+ * 检查权限(subject 为 Message 通讯上下文)
35
36
  */
36
- check(name: string, message: MessageClass<AdapterMessage<RegisteredAdapter>>): Promise<boolean>;
37
+ check(name: string, subject: PermissionSubject): Promise<boolean>;
37
38
  /**
38
39
  * 序列化为 JSON
39
40
  */
@@ -48,8 +49,3 @@ export declare class PermissionFeature extends Feature<PermissionItem> {
48
49
  export declare namespace Permissions {
49
50
  function define<T extends RegisteredAdapter = RegisteredAdapter>(name: string | RegExp, check: PermissionChecker<T>): PermissionItem<T>;
50
51
  }
51
- /**
52
- * @deprecated Use PermissionFeature instead
53
- */
54
- export declare const PermissionService: typeof PermissionFeature;
55
- //# sourceMappingURL=permission.d.ts.map