@zhin.js/core 1.3.1 → 1.3.3

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 (358) hide show
  1. package/README.md +66 -11
  2. package/lib/adapter.d.ts +41 -3
  3. package/lib/adapter.js +110 -6
  4. package/lib/agent-prompt.d.ts +0 -1
  5. package/lib/agent-prompt.js +0 -1
  6. package/lib/built/adapter-process.d.ts +11 -2
  7. package/lib/built/adapter-process.js +43 -2
  8. package/lib/built/agent-preset.d.ts +0 -1
  9. package/lib/built/agent-preset.js +0 -1
  10. package/lib/built/ai-access.d.ts +36 -0
  11. package/lib/built/ai-access.js +46 -0
  12. package/lib/built/ai-outbound/adapter-access.d.ts +3 -0
  13. package/lib/built/ai-outbound/adapter-access.js +9 -0
  14. package/lib/built/ai-outbound/extensions/onebot-keyboard.d.ts +2 -0
  15. package/lib/built/ai-outbound/extensions/onebot-keyboard.js +67 -0
  16. package/lib/built/ai-outbound/extensions/qq-message.d.ts +3 -0
  17. package/lib/built/ai-outbound/extensions/qq-message.js +23 -0
  18. package/lib/built/ai-outbound/index.d.ts +9 -0
  19. package/lib/built/ai-outbound/index.js +9 -0
  20. package/lib/built/ai-outbound/parse.d.ts +13 -0
  21. package/lib/built/ai-outbound/parse.js +94 -0
  22. package/lib/built/ai-outbound/plain-mention-rewrite.d.ts +6 -0
  23. package/lib/built/ai-outbound/plain-mention-rewrite.js +37 -0
  24. package/lib/built/ai-outbound/prompt.d.ts +11 -0
  25. package/lib/built/ai-outbound/prompt.js +44 -0
  26. package/lib/built/ai-outbound/resolve.d.ts +4 -0
  27. package/lib/built/ai-outbound/resolve.js +64 -0
  28. package/lib/built/ai-outbound/structured-detect.d.ts +3 -0
  29. package/lib/built/ai-outbound/structured-detect.js +7 -0
  30. package/lib/built/ai-outbound/types.d.ts +60 -0
  31. package/lib/built/ai-outbound/types.js +5 -0
  32. package/lib/built/ai-trigger.d.ts +5 -1
  33. package/lib/built/ai-trigger.js +3 -7
  34. package/lib/built/authorization.d.ts +0 -1
  35. package/lib/built/authorization.js +0 -1
  36. package/lib/built/command.d.ts +2 -1
  37. package/lib/built/command.js +14 -4
  38. package/lib/built/common-adapter-tools.d.ts +25 -26
  39. package/lib/built/common-adapter-tools.js +48 -49
  40. package/lib/built/component.d.ts +0 -1
  41. package/lib/built/component.js +1 -3
  42. package/lib/built/config.d.ts +4 -1
  43. package/lib/built/config.js +26 -5
  44. package/lib/built/connect-endpoint-instance.d.ts +0 -1
  45. package/lib/built/connect-endpoint-instance.js +3 -2
  46. package/lib/built/database.d.ts +0 -1
  47. package/lib/built/database.js +1 -3
  48. package/lib/built/dispatcher.d.ts +6 -6
  49. package/lib/built/dispatcher.js +20 -8
  50. package/lib/built/endpoint-commands.d.ts +3 -0
  51. package/lib/built/endpoint-commands.js +99 -0
  52. package/lib/built/endpoint-lifecycle-service.d.ts +28 -0
  53. package/lib/built/endpoint-lifecycle-service.js +241 -0
  54. package/lib/built/endpoint-lifecycle.d.ts +0 -1
  55. package/lib/built/endpoint-lifecycle.js +0 -1
  56. package/lib/built/endpoint-manager.d.ts +34 -0
  57. package/lib/built/endpoint-manager.js +1 -0
  58. package/lib/built/generated-qrcode.d.ts +24 -0
  59. package/lib/built/generated-qrcode.js +45 -0
  60. package/lib/built/generic-segment-mapper.d.ts +6 -0
  61. package/lib/built/generic-segment-mapper.js +232 -0
  62. package/lib/built/html-renderer-loader.d.ts +13 -0
  63. package/lib/built/html-renderer-loader.js +33 -0
  64. package/lib/built/html-segment-fallback.d.ts +2 -2
  65. package/lib/built/html-segment-fallback.js +0 -1
  66. package/lib/built/html-to-text.d.ts +0 -1
  67. package/lib/built/html-to-text.js +0 -1
  68. package/lib/built/inbound-pipeline.d.ts +0 -1
  69. package/lib/built/inbound-pipeline.js +0 -1
  70. package/lib/built/inbound-runner.d.ts +0 -1
  71. package/lib/built/inbound-runner.js +0 -1
  72. package/lib/built/interactive-segment-contract.d.ts +6 -0
  73. package/lib/built/interactive-segment-contract.js +9 -0
  74. package/lib/built/interactive-segments/action.d.ts +17 -0
  75. package/lib/built/interactive-segments/action.js +54 -0
  76. package/lib/built/interactive-segments/button-spec.d.ts +10 -0
  77. package/lib/built/interactive-segments/button-spec.js +21 -0
  78. package/lib/built/interactive-segments/handlers.d.ts +9 -0
  79. package/lib/built/interactive-segments/handlers.js +58 -0
  80. package/lib/built/interactive-segments/index.d.ts +7 -0
  81. package/lib/built/interactive-segments/index.js +7 -0
  82. package/lib/built/interactive-segments/keyboard-segment.d.ts +12 -0
  83. package/lib/built/interactive-segments/keyboard-segment.js +13 -0
  84. package/lib/built/interactive-segments/onebot-keyboard.d.ts +10 -0
  85. package/lib/built/interactive-segments/onebot-keyboard.js +53 -0
  86. package/lib/built/interactive-segments/resolve.d.ts +9 -0
  87. package/lib/built/interactive-segments/resolve.js +84 -0
  88. package/lib/built/interactive-segments/types.d.ts +62 -0
  89. package/lib/built/interactive-segments/types.js +13 -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 +1 -2
  93. package/lib/built/login-assist.js +0 -1
  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 +0 -1
  97. package/lib/built/message-enrich.js +0 -1
  98. package/lib/built/message-filter.d.ts +0 -1
  99. package/lib/built/message-filter.js +1 -3
  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 +0 -1
  107. package/lib/built/permission.js +1 -3
  108. package/lib/built/permit-check.d.ts +0 -1
  109. package/lib/built/permit-check.js +0 -1
  110. package/lib/built/permit-parse.d.ts +0 -1
  111. package/lib/built/permit-parse.js +0 -1
  112. package/lib/built/platform-permit.d.ts +5 -6
  113. package/lib/built/platform-permit.js +11 -12
  114. package/lib/built/prepend-quote-context.d.ts +0 -1
  115. package/lib/built/prepend-quote-context.js +0 -1
  116. package/lib/built/qrcode-segment.d.ts +18 -0
  117. package/lib/built/qrcode-segment.js +78 -0
  118. package/lib/built/queue-im-field-contract.d.ts +6 -1
  119. package/lib/built/queue-im-field-contract.js +10 -1
  120. package/lib/built/rich-segments/adapter-policies.d.ts +9 -0
  121. package/lib/built/rich-segments/adapter-policies.js +27 -0
  122. package/lib/built/rich-segments/base.d.ts +11 -0
  123. package/lib/built/rich-segments/base.js +24 -0
  124. package/lib/built/rich-segments/builtins.d.ts +4 -0
  125. package/lib/built/rich-segments/builtins.js +40 -0
  126. package/lib/built/rich-segments/capabilities.d.ts +6 -0
  127. package/lib/built/rich-segments/capabilities.js +39 -0
  128. package/lib/built/rich-segments/html-segment.d.ts +15 -0
  129. package/lib/built/rich-segments/html-segment.js +65 -0
  130. package/lib/built/rich-segments/index.d.ts +13 -0
  131. package/lib/built/rich-segments/index.js +13 -0
  132. package/lib/built/rich-segments/markdown-segment.d.ts +14 -0
  133. package/lib/built/rich-segments/markdown-segment.js +61 -0
  134. package/lib/built/rich-segments/markdown-to-text.d.ts +3 -0
  135. package/lib/built/rich-segments/markdown-to-text.js +27 -0
  136. package/lib/built/rich-segments/qrcode-segment.d.ts +18 -0
  137. package/lib/built/rich-segments/qrcode-segment.js +73 -0
  138. package/lib/built/rich-segments/registry.d.ts +16 -0
  139. package/lib/built/rich-segments/registry.js +52 -0
  140. package/lib/built/rich-segments/resolve.d.ts +5 -0
  141. package/lib/built/rich-segments/resolve.js +87 -0
  142. package/lib/built/rich-segments/tts-segment.d.ts +13 -0
  143. package/lib/built/rich-segments/tts-segment.js +51 -0
  144. package/lib/built/rich-segments/types.d.ts +84 -0
  145. package/lib/built/rich-segments/types.js +17 -0
  146. package/lib/built/roles.d.ts +0 -1
  147. package/lib/built/roles.js +0 -1
  148. package/lib/built/runtime-io.d.ts +0 -1
  149. package/lib/built/runtime-io.js +0 -1
  150. package/lib/built/schedule.d.ts +55 -0
  151. package/lib/built/schedule.js +112 -0
  152. package/lib/built/schema-endpoint-manager.d.ts +17 -0
  153. package/lib/built/schema-endpoint-manager.js +73 -0
  154. package/lib/built/schema-feature.d.ts +0 -1
  155. package/lib/built/schema-feature.js +1 -3
  156. package/lib/built/segment-contract/assert.d.ts +4 -0
  157. package/lib/built/segment-contract/assert.js +30 -0
  158. package/lib/built/segment-contract/delivery.d.ts +5 -0
  159. package/lib/built/segment-contract/delivery.js +40 -0
  160. package/lib/built/segment-contract/image.d.ts +5 -0
  161. package/lib/built/segment-contract/image.js +10 -0
  162. package/lib/built/segment-contract/index.d.ts +8 -0
  163. package/lib/built/segment-contract/index.js +7 -0
  164. package/lib/built/segment-contract/media.d.ts +8 -0
  165. package/lib/built/segment-contract/media.js +39 -0
  166. package/lib/built/segment-contract/mention.d.ts +10 -0
  167. package/lib/built/segment-contract/mention.js +26 -0
  168. package/lib/built/segment-contract/preview.d.ts +3 -0
  169. package/lib/built/segment-contract/preview.js +159 -0
  170. package/lib/built/segment-contract/types.d.ts +70 -0
  171. package/lib/built/segment-contract/types.js +5 -0
  172. package/lib/built/segment-contract/validate.d.ts +138 -0
  173. package/lib/built/segment-contract/validate.js +124 -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 +0 -1
  179. package/lib/built/tool.js +1 -3
  180. package/lib/command.d.ts +12 -7
  181. package/lib/command.js +38 -16
  182. package/lib/component.d.ts +0 -1
  183. package/lib/component.js +0 -1
  184. package/lib/endpoint-capabilities.d.ts +3 -1
  185. package/lib/endpoint-capabilities.js +0 -1
  186. package/lib/endpoint.d.ts +0 -1
  187. package/lib/endpoint.js +0 -1
  188. package/lib/errors.d.ts +0 -1
  189. package/lib/errors.js +0 -1
  190. package/lib/host-plugin-registry.d.ts +0 -1
  191. package/lib/host-plugin-registry.js +0 -1
  192. package/lib/im-scene.d.ts +29 -0
  193. package/lib/im-scene.js +77 -0
  194. package/lib/im-session-id.d.ts +25 -12
  195. package/lib/im-session-id.js +35 -17
  196. package/lib/index.d.ts +25 -5
  197. package/lib/index.js +22 -4
  198. package/lib/jsx-dev-runtime.d.ts +0 -1
  199. package/lib/jsx-dev-runtime.js +0 -1
  200. package/lib/jsx-runtime.d.ts +0 -1
  201. package/lib/jsx-runtime.js +0 -1
  202. package/lib/jsx.d.ts +0 -1
  203. package/lib/jsx.js +0 -1
  204. package/lib/message-quote.d.ts +1 -2
  205. package/lib/message-quote.js +2 -3
  206. package/lib/message.d.ts +12 -2
  207. package/lib/message.js +16 -1
  208. package/lib/models/system-log.d.ts +0 -1
  209. package/lib/models/system-log.js +0 -1
  210. package/lib/models/user.d.ts +0 -1
  211. package/lib/models/user.js +0 -1
  212. package/lib/notice.d.ts +0 -1
  213. package/lib/notice.js +0 -1
  214. package/lib/plugin-context.d.ts +0 -1
  215. package/lib/plugin-context.js +0 -1
  216. package/lib/plugin.d.ts +11 -2
  217. package/lib/plugin.js +22 -23
  218. package/lib/prompt.d.ts +0 -1
  219. package/lib/prompt.js +1 -2
  220. package/lib/request.d.ts +0 -1
  221. package/lib/request.js +0 -1
  222. package/lib/tool-zod.d.ts +0 -1
  223. package/lib/tool-zod.js +0 -1
  224. package/lib/types-generator.d.ts +0 -1
  225. package/lib/types-generator.js +0 -1
  226. package/lib/types.d.ts +30 -11
  227. package/lib/types.js +0 -1
  228. package/lib/utils.d.ts +57 -12
  229. package/lib/utils.js +54 -19
  230. package/package.json +18 -9
  231. package/lib/adapter.d.ts.map +0 -1
  232. package/lib/adapter.js.map +0 -1
  233. package/lib/agent-prompt.d.ts.map +0 -1
  234. package/lib/agent-prompt.js.map +0 -1
  235. package/lib/built/adapter-process.d.ts.map +0 -1
  236. package/lib/built/adapter-process.js.map +0 -1
  237. package/lib/built/agent-preset.d.ts.map +0 -1
  238. package/lib/built/agent-preset.js.map +0 -1
  239. package/lib/built/ai-trigger.d.ts.map +0 -1
  240. package/lib/built/ai-trigger.js.map +0 -1
  241. package/lib/built/authorization.d.ts.map +0 -1
  242. package/lib/built/authorization.js.map +0 -1
  243. package/lib/built/command.d.ts.map +0 -1
  244. package/lib/built/command.js.map +0 -1
  245. package/lib/built/common-adapter-tools.d.ts.map +0 -1
  246. package/lib/built/common-adapter-tools.js.map +0 -1
  247. package/lib/built/component.d.ts.map +0 -1
  248. package/lib/built/component.js.map +0 -1
  249. package/lib/built/config.d.ts.map +0 -1
  250. package/lib/built/config.js.map +0 -1
  251. package/lib/built/connect-endpoint-instance.d.ts.map +0 -1
  252. package/lib/built/connect-endpoint-instance.js.map +0 -1
  253. package/lib/built/cron.d.ts +0 -75
  254. package/lib/built/cron.d.ts.map +0 -1
  255. package/lib/built/cron.js +0 -122
  256. package/lib/built/cron.js.map +0 -1
  257. package/lib/built/database.d.ts.map +0 -1
  258. package/lib/built/database.js.map +0 -1
  259. package/lib/built/dispatcher.d.ts.map +0 -1
  260. package/lib/built/dispatcher.js.map +0 -1
  261. package/lib/built/endpoint-lifecycle.d.ts.map +0 -1
  262. package/lib/built/endpoint-lifecycle.js.map +0 -1
  263. package/lib/built/html-segment-fallback.d.ts.map +0 -1
  264. package/lib/built/html-segment-fallback.js.map +0 -1
  265. package/lib/built/html-to-text.d.ts.map +0 -1
  266. package/lib/built/html-to-text.js.map +0 -1
  267. package/lib/built/inbound-pipeline.d.ts.map +0 -1
  268. package/lib/built/inbound-pipeline.js.map +0 -1
  269. package/lib/built/inbound-runner.d.ts.map +0 -1
  270. package/lib/built/inbound-runner.js.map +0 -1
  271. package/lib/built/login-assist.d.ts.map +0 -1
  272. package/lib/built/login-assist.js.map +0 -1
  273. package/lib/built/mcp-mesh-registrar.d.ts +0 -9
  274. package/lib/built/mcp-mesh-registrar.d.ts.map +0 -1
  275. package/lib/built/mcp-mesh-registrar.js +0 -17
  276. package/lib/built/mcp-mesh-registrar.js.map +0 -1
  277. package/lib/built/message-enrich.d.ts.map +0 -1
  278. package/lib/built/message-enrich.js.map +0 -1
  279. package/lib/built/message-filter.d.ts.map +0 -1
  280. package/lib/built/message-filter.js.map +0 -1
  281. package/lib/built/permission.d.ts.map +0 -1
  282. package/lib/built/permission.js.map +0 -1
  283. package/lib/built/permit-check.d.ts.map +0 -1
  284. package/lib/built/permit-check.js.map +0 -1
  285. package/lib/built/permit-parse.d.ts.map +0 -1
  286. package/lib/built/permit-parse.js.map +0 -1
  287. package/lib/built/platform-permit.d.ts.map +0 -1
  288. package/lib/built/platform-permit.js.map +0 -1
  289. package/lib/built/prepend-quote-context.d.ts.map +0 -1
  290. package/lib/built/prepend-quote-context.js.map +0 -1
  291. package/lib/built/queue-im-field-contract.d.ts.map +0 -1
  292. package/lib/built/queue-im-field-contract.js.map +0 -1
  293. package/lib/built/roles.d.ts.map +0 -1
  294. package/lib/built/roles.js.map +0 -1
  295. package/lib/built/runtime-io.d.ts.map +0 -1
  296. package/lib/built/runtime-io.js.map +0 -1
  297. package/lib/built/schema-feature.d.ts.map +0 -1
  298. package/lib/built/schema-feature.js.map +0 -1
  299. package/lib/built/skill.d.ts.map +0 -1
  300. package/lib/built/skill.js.map +0 -1
  301. package/lib/built/tool.d.ts.map +0 -1
  302. package/lib/built/tool.js.map +0 -1
  303. package/lib/command.d.ts.map +0 -1
  304. package/lib/command.js.map +0 -1
  305. package/lib/component.d.ts.map +0 -1
  306. package/lib/component.js.map +0 -1
  307. package/lib/endpoint-capabilities.d.ts.map +0 -1
  308. package/lib/endpoint-capabilities.js.map +0 -1
  309. package/lib/endpoint.d.ts.map +0 -1
  310. package/lib/endpoint.js.map +0 -1
  311. package/lib/errors.d.ts.map +0 -1
  312. package/lib/errors.js.map +0 -1
  313. package/lib/host-plugin-registry.d.ts.map +0 -1
  314. package/lib/host-plugin-registry.js.map +0 -1
  315. package/lib/im-session-id.d.ts.map +0 -1
  316. package/lib/im-session-id.js.map +0 -1
  317. package/lib/index.d.ts.map +0 -1
  318. package/lib/index.js.map +0 -1
  319. package/lib/jsx-dev-runtime.d.ts.map +0 -1
  320. package/lib/jsx-dev-runtime.js.map +0 -1
  321. package/lib/jsx-runtime.d.ts.map +0 -1
  322. package/lib/jsx-runtime.js.map +0 -1
  323. package/lib/jsx.d.ts.map +0 -1
  324. package/lib/jsx.js.map +0 -1
  325. package/lib/message-quote.d.ts.map +0 -1
  326. package/lib/message-quote.js.map +0 -1
  327. package/lib/message.d.ts.map +0 -1
  328. package/lib/message.js.map +0 -1
  329. package/lib/models/system-log.d.ts.map +0 -1
  330. package/lib/models/system-log.js.map +0 -1
  331. package/lib/models/user.d.ts.map +0 -1
  332. package/lib/models/user.js.map +0 -1
  333. package/lib/notice.d.ts.map +0 -1
  334. package/lib/notice.js.map +0 -1
  335. package/lib/plugin-context.d.ts.map +0 -1
  336. package/lib/plugin-context.js.map +0 -1
  337. package/lib/plugin.d.ts.map +0 -1
  338. package/lib/plugin.js.map +0 -1
  339. package/lib/prompt.d.ts.map +0 -1
  340. package/lib/prompt.js.map +0 -1
  341. package/lib/request.d.ts.map +0 -1
  342. package/lib/request.js.map +0 -1
  343. package/lib/scheduler/scheduler.d.ts +0 -49
  344. package/lib/scheduler/scheduler.d.ts.map +0 -1
  345. package/lib/scheduler/scheduler.js +0 -352
  346. package/lib/scheduler/scheduler.js.map +0 -1
  347. package/lib/scheduler/types.d.ts +0 -71
  348. package/lib/scheduler/types.d.ts.map +0 -1
  349. package/lib/scheduler/types.js +0 -8
  350. package/lib/scheduler/types.js.map +0 -1
  351. package/lib/tool-zod.d.ts.map +0 -1
  352. package/lib/tool-zod.js.map +0 -1
  353. package/lib/types-generator.d.ts.map +0 -1
  354. package/lib/types-generator.js.map +0 -1
  355. package/lib/types.d.ts.map +0 -1
  356. package/lib/types.js.map +0 -1
  357. package/lib/utils.d.ts.map +0 -1
  358. package/lib/utils.js.map +0 -1
@@ -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
+ }
@@ -53,4 +53,3 @@ export declare namespace Permissions {
53
53
  * @deprecated Use PermissionFeature instead
54
54
  */
55
55
  export declare const PermissionService: typeof PermissionFeature;
56
- //# sourceMappingURL=permission.d.ts.map
@@ -4,7 +4,6 @@
4
4
  */
5
5
  import { Feature } from "@zhin.js/kernel";
6
6
  import logger, { formatCompact } from "@zhin.js/logger";
7
- import { getPlugin } from "../plugin.js";
8
7
  import { isBuiltinPermit, parsePermitName } from "./permit-parse.js";
9
8
  import { checkBuiltinPermit } from "./permit-check.js";
10
9
  import { senderRolesFromMessage } from "./message-enrich.js";
@@ -81,7 +80,7 @@ export class PermissionFeature extends Feature {
81
80
  const feature = this;
82
81
  return {
83
82
  addPermission(permission) {
84
- const plugin = getPlugin();
83
+ const plugin = this;
85
84
  const dispose = feature.add(permission, plugin.name);
86
85
  const permName = permission.name instanceof RegExp ? permission.name.source : permission.name;
87
86
  plugin.recordFeatureContribution(feature.name, permName);
@@ -102,4 +101,3 @@ export var Permissions;
102
101
  * @deprecated Use PermissionFeature instead
103
102
  */
104
103
  export const PermissionService = PermissionFeature;
105
- //# sourceMappingURL=permission.js.map
@@ -5,4 +5,3 @@ import type { Message } from '../message.js';
5
5
  import type { SenderRole } from './roles.js';
6
6
  export declare function checkBuiltinPermit(name: string, message: Message<any>, roles: readonly SenderRole[]): boolean;
7
7
  export declare function checkBuiltinPermitList(permits: readonly string[], message: Message<any>, roles: readonly SenderRole[]): boolean;
8
- //# sourceMappingURL=permit-check.d.ts.map
@@ -33,4 +33,3 @@ export function checkBuiltinPermit(name, message, roles) {
33
33
  export function checkBuiltinPermitList(permits, message, roles) {
34
34
  return permits.every((p) => checkBuiltinPermit(p, message, roles));
35
35
  }
36
- //# sourceMappingURL=permit-check.js.map
@@ -14,4 +14,3 @@ export interface ParsedPlatformPermit {
14
14
  }
15
15
  export declare function parsePlatformPermitName(name: string): ParsedPlatformPermit | null;
16
16
  export declare function isPlatformPermit(name: string): boolean;
17
- //# sourceMappingURL=permit-parse.d.ts.map
@@ -30,4 +30,3 @@ export function parsePlatformPermitName(name) {
30
30
  export function isPlatformPermit(name) {
31
31
  return PLATFORM_PERMIT_RE.test(name);
32
32
  }
33
- //# sourceMappingURL=permit-parse.js.map
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Platform permit — 适配器注册的平台级权限校验(群管、频道身份等)
2
+ * Platform permit — 适配器注册的平台级权限校验(场景治理、频道身份等)
3
3
  */
4
4
  import type { Message } from '../message.js';
5
5
  export type PlatformPermitChecker = (perm: string, message: Message<any>) => boolean;
@@ -14,8 +14,7 @@ export declare function applyQqSenderRoleToMessageSender(sender: {
14
14
  role?: string;
15
15
  permissions?: string[];
16
16
  }, role?: string): void;
17
- /** 常见 IM 平台群身份:$sender.role 为 owner / admin */
18
- export declare function createGroupRolePlatformChecker(): PlatformPermitChecker;
19
- /** 为适配器注册默认群管 platform checker(幂等) */
20
- export declare function registerDefaultGroupPlatformPermitChecker(adapter: string): () => void;
21
- //# sourceMappingURL=platform-permit.d.ts.map
17
+ /** 常见 IM 平台场景身份:$sender.role 为 owner / admin */
18
+ export declare function createSceneRolePlatformChecker(): PlatformPermitChecker;
19
+ /** 为适配器注册默认场景治理 platform checker(幂等) */
20
+ export declare function registerDefaultScenePlatformPermitChecker(adapter: string): () => void;
@@ -1,6 +1,6 @@
1
1
  import { parsePlatformPermitName, isPlatformPermit } from './permit-parse.js';
2
2
  const checkers = new Map();
3
- const registeredDefaultGroupCheckers = new Set();
3
+ const registeredDefaultSceneCheckers = new Set();
4
4
  export function registerPlatformPermitChecker(adapter, checker) {
5
5
  const key = String(adapter);
6
6
  checkers.set(key, checker);
@@ -12,7 +12,7 @@ export function registerPlatformPermitChecker(adapter, checker) {
12
12
  }
13
13
  export function clearPlatformPermitCheckers() {
14
14
  checkers.clear();
15
- registeredDefaultGroupCheckers.clear();
15
+ registeredDefaultSceneCheckers.clear();
16
16
  }
17
17
  export function checkPlatformPermit(name, message) {
18
18
  const parsed = parsePlatformPermitName(name);
@@ -44,24 +44,23 @@ export function applyQqSenderRoleToMessageSender(sender, role) {
44
44
  sender.role = normalized;
45
45
  sender.permissions = [normalized];
46
46
  }
47
- /** 常见 IM 平台群身份:$sender.role 为 owner / admin */
48
- export function createGroupRolePlatformChecker() {
47
+ /** 常见 IM 平台场景身份:$sender.role 为 owner / admin */
48
+ export function createSceneRolePlatformChecker() {
49
49
  return (perm, message) => {
50
50
  const role = message.$sender?.role;
51
- if (perm === 'group_admin')
51
+ if (perm === 'scene_admin')
52
52
  return role === 'admin' || role === 'owner';
53
- if (perm === 'group_owner')
53
+ if (perm === 'scene_owner')
54
54
  return role === 'owner';
55
55
  return false;
56
56
  };
57
57
  }
58
- /** 为适配器注册默认群管 platform checker(幂等) */
59
- export function registerDefaultGroupPlatformPermitChecker(adapter) {
58
+ /** 为适配器注册默认场景治理 platform checker(幂等) */
59
+ export function registerDefaultScenePlatformPermitChecker(adapter) {
60
60
  const key = String(adapter);
61
- if (registeredDefaultGroupCheckers.has(key)) {
61
+ if (registeredDefaultSceneCheckers.has(key)) {
62
62
  return () => { };
63
63
  }
64
- registeredDefaultGroupCheckers.add(key);
65
- return registerPlatformPermitChecker(key, createGroupRolePlatformChecker());
64
+ registeredDefaultSceneCheckers.add(key);
65
+ return registerPlatformPermitChecker(key, createSceneRolePlatformChecker());
66
66
  }
67
- //# sourceMappingURL=platform-permit.js.map
@@ -32,4 +32,3 @@ export declare function resolveQuoteContextBlock(message: Message<any>, root: Pl
32
32
  export declare function prependQuoteContext(message: Message<any>, root: Plugin, userText: string, options?: {
33
33
  enabled?: boolean;
34
34
  }): Promise<string>;
35
- //# sourceMappingURL=prepend-quote-context.d.ts.map
@@ -128,4 +128,3 @@ export async function prependQuoteContext(message, root, userText, options) {
128
128
  const quoteBlock = await resolveQuoteContextBlock(message, root, options);
129
129
  return buildUserTurnWithQuoteContext(userText, quoteBlock);
130
130
  }
131
- //# sourceMappingURL=prepend-quote-context.js.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 出站 `qrcode` 消息段(legacy 导出;新代码请用 rich-segments)。
3
+ * @deprecated 出站渲染由 Adapter.renderSendMessage → resolveRichSegments 统一处理
4
+ */
5
+ import type { SendContent } from '../types.js';
6
+ import { QrcodeSegment, readQrcodeSegmentData, type QrcodeSegmentData } from './rich-segments/qrcode-segment.js';
7
+ export type { QrcodeSegmentData };
8
+ export { QrcodeSegment, readQrcodeSegmentData };
9
+ export type QrcodeOutboundMode = 'image' | 'terminal' | 'text';
10
+ export declare function hasQrcodeSegment(content: SendContent | undefined): boolean;
11
+ /** 创建 qrcode 出站段 */
12
+ export declare function qrcodeSegment(text: string, options?: Omit<QrcodeSegmentData, 'text'>): QrcodeSegment;
13
+ /** IM 适配器:qrcode → image(data URL + base64) */
14
+ export declare function resolveQrcodeSegmentsToImages(content: SendContent | undefined): Promise<SendContent | undefined>;
15
+ /** process 适配器:终端 ASCII + 文本占位(legacy;process endpoint 现解释 origin qrcode) */
16
+ export declare function resolveQrcodeSegmentsToTerminal(content: SendContent | undefined): Promise<SendContent | undefined>;
17
+ /** 不支持图片的平台:仅输出链接文本 */
18
+ export declare function coerceQrcodeSegmentsToText(content: SendContent): SendContent;
@@ -0,0 +1,78 @@
1
+ import { segment } from '../utils.js';
2
+ import { GeneratedQrCode } from './generated-qrcode.js';
3
+ import { QrcodeSegment, readQrcodeSegmentData, } from './rich-segments/qrcode-segment.js';
4
+ export { QrcodeSegment, readQrcodeSegmentData };
5
+ function asArray(content) {
6
+ return Array.isArray(content) ? content : [content];
7
+ }
8
+ function packSegments(out) {
9
+ if (out.length === 0)
10
+ return segment.text('');
11
+ if (out.length === 1)
12
+ return out[0];
13
+ return out;
14
+ }
15
+ export function hasQrcodeSegment(content) {
16
+ if (content == null)
17
+ return false;
18
+ return asArray(content).some((item) => typeof item !== 'string' && item?.type === 'qrcode');
19
+ }
20
+ /** 创建 qrcode 出站段 */
21
+ export function qrcodeSegment(text, options = {}) {
22
+ return new QrcodeSegment({ text, ...options });
23
+ }
24
+ const LEGACY_QRCODE_ONLY_POLICY = {
25
+ qrcode: 'image',
26
+ html: 'origin',
27
+ markdown: 'origin',
28
+ };
29
+ /** IM 适配器:qrcode → image(data URL + base64) */
30
+ export async function resolveQrcodeSegmentsToImages(content) {
31
+ if (content == null)
32
+ return content;
33
+ const { resolveRichSegments } = await import('./rich-segments/index.js');
34
+ return resolveRichSegments(content, LEGACY_QRCODE_ONLY_POLICY);
35
+ }
36
+ /** process 适配器:终端 ASCII + 文本占位(legacy;process endpoint 现解释 origin qrcode) */
37
+ export async function resolveQrcodeSegmentsToTerminal(content) {
38
+ if (content == null)
39
+ return content;
40
+ if (!hasQrcodeSegment(content))
41
+ return content;
42
+ const items = asArray(content);
43
+ const out = [];
44
+ for (const item of items) {
45
+ if (typeof item === 'string') {
46
+ out.push(item);
47
+ continue;
48
+ }
49
+ if (item.type !== 'qrcode') {
50
+ out.push(item);
51
+ continue;
52
+ }
53
+ const payload = readQrcodeSegmentData(item.data ?? {});
54
+ const qr = await GeneratedQrCode.generate(payload.text, payload);
55
+ await qr.printToTerminal({ small: payload.small ?? true });
56
+ out.push(segment.text(`[二维码] ${payload.text}`));
57
+ }
58
+ return packSegments(out);
59
+ }
60
+ /** 不支持图片的平台:仅输出链接文本 */
61
+ export function coerceQrcodeSegmentsToText(content) {
62
+ const items = asArray(content);
63
+ const out = [];
64
+ for (const item of items) {
65
+ if (typeof item === 'string') {
66
+ out.push(item);
67
+ continue;
68
+ }
69
+ if (item?.type === 'qrcode') {
70
+ const text = typeof item.data?.text === 'string' ? item.data.text : '';
71
+ if (text)
72
+ out.push(segment.text(`[二维码] ${text}`));
73
+ continue;
74
+ }
75
+ out.push(item);
76
+ }
77
+ return packSegments(out);
78
+ }
@@ -1,5 +1,6 @@
1
1
  import type { MessageType } from '../message.js';
2
2
  import type { SendContent, SendOptions } from '../types.js';
3
+ import { type IMDeliveryTarget } from '../im-scene.js';
3
4
  export interface QueueEnvelope<TDetail extends Record<string, unknown> = Record<string, unknown>> {
4
5
  kind: string;
5
6
  type: string;
@@ -23,5 +24,9 @@ export declare function isMessageType(value: unknown): value is MessageType;
23
24
  /** Normalize queue outbound detail into the canonical queue-IM shape. */
24
25
  export declare function normalizeQueueOutboundDetail(record: Record<string, unknown>): NormalizedQueueOutboundDetail;
25
26
  export declare function toSendOptions(detail: NormalizedQueueOutboundDetail): SendOptions;
27
+ export interface QueueIMSceneTargetDetail {
28
+ target: IMDeliveryTarget;
29
+ content: SendContent;
30
+ }
31
+ export declare function sceneTargetToSendOptions(detail: QueueIMSceneTargetDetail): SendOptions;
26
32
  export declare function normalizeRecordToSendOptions(record: Record<string, unknown>): SendOptions;
27
- //# sourceMappingURL=queue-im-field-contract.d.ts.map
@@ -1,3 +1,4 @@
1
+ import { sceneRefToSendOptions } from '../im-scene.js';
1
2
  export class QueueIMFieldContractError extends Error {
2
3
  code;
3
4
  field;
@@ -52,7 +53,15 @@ export function toSendOptions(detail) {
52
53
  content: detail.content,
53
54
  };
54
55
  }
56
+ export function sceneTargetToSendOptions(detail) {
57
+ return sceneRefToSendOptions(detail.target, detail.content);
58
+ }
55
59
  export function normalizeRecordToSendOptions(record) {
60
+ if (record.target && typeof record.target === 'object') {
61
+ return sceneTargetToSendOptions({
62
+ target: record.target,
63
+ content: requireContent(record.content),
64
+ });
65
+ }
56
66
  return toSendOptions(normalizeQueueOutboundDetail(record));
57
67
  }
58
- //# sourceMappingURL=queue-im-field-contract.js.map
@@ -0,0 +1,9 @@
1
+ import { type OutboundRichSegmentPolicy } from './types.js';
2
+ /** 全功能 IM:html/markdown/qrcode→image,tts→audio */
3
+ export declare const OUTBOUND_RICH_SEGMENT_POLICY_IM_FULL: OutboundRichSegmentPolicy;
4
+ /** 仅文本降级(无富媒体出站能力) */
5
+ export declare const OUTBOUND_RICH_SEGMENT_POLICY_TEXT_ONLY: OutboundRichSegmentPolicy;
6
+ /** 默认 registry 等价(html/markdown 文本,qrcode 图片,tts 音频) */
7
+ export declare const OUTBOUND_RICH_SEGMENT_POLICY_IM_DEFAULT: OutboundRichSegmentPolicy;
8
+ /** 无音频出站(tts 降级 text) */
9
+ export declare const OUTBOUND_RICH_SEGMENT_POLICY_NO_AUDIO: OutboundRichSegmentPolicy;
@@ -0,0 +1,27 @@
1
+ import { BUILTIN_RICH_SEGMENT_KINDS, RICH_SEGMENT_MODE } from './types.js';
2
+ /** 全功能 IM:html/markdown/qrcode→image,tts→audio */
3
+ export const OUTBOUND_RICH_SEGMENT_POLICY_IM_FULL = {
4
+ [BUILTIN_RICH_SEGMENT_KINDS.QRCODE]: RICH_SEGMENT_MODE.IMAGE,
5
+ [BUILTIN_RICH_SEGMENT_KINDS.HTML]: RICH_SEGMENT_MODE.IMAGE,
6
+ [BUILTIN_RICH_SEGMENT_KINDS.MARKDOWN]: RICH_SEGMENT_MODE.IMAGE,
7
+ [BUILTIN_RICH_SEGMENT_KINDS.TTS]: RICH_SEGMENT_MODE.AUDIO,
8
+ };
9
+ /** 仅文本降级(无富媒体出站能力) */
10
+ export const OUTBOUND_RICH_SEGMENT_POLICY_TEXT_ONLY = {
11
+ [BUILTIN_RICH_SEGMENT_KINDS.QRCODE]: RICH_SEGMENT_MODE.TEXT,
12
+ [BUILTIN_RICH_SEGMENT_KINDS.HTML]: RICH_SEGMENT_MODE.TEXT,
13
+ [BUILTIN_RICH_SEGMENT_KINDS.MARKDOWN]: RICH_SEGMENT_MODE.TEXT,
14
+ [BUILTIN_RICH_SEGMENT_KINDS.TTS]: RICH_SEGMENT_MODE.TEXT,
15
+ };
16
+ /** 默认 registry 等价(html/markdown 文本,qrcode 图片,tts 音频) */
17
+ export const OUTBOUND_RICH_SEGMENT_POLICY_IM_DEFAULT = {
18
+ [BUILTIN_RICH_SEGMENT_KINDS.QRCODE]: RICH_SEGMENT_MODE.IMAGE,
19
+ [BUILTIN_RICH_SEGMENT_KINDS.HTML]: RICH_SEGMENT_MODE.TEXT,
20
+ [BUILTIN_RICH_SEGMENT_KINDS.MARKDOWN]: RICH_SEGMENT_MODE.TEXT,
21
+ [BUILTIN_RICH_SEGMENT_KINDS.TTS]: RICH_SEGMENT_MODE.AUDIO,
22
+ };
23
+ /** 无音频出站(tts 降级 text) */
24
+ export const OUTBOUND_RICH_SEGMENT_POLICY_NO_AUDIO = {
25
+ ...OUTBOUND_RICH_SEGMENT_POLICY_IM_FULL,
26
+ [BUILTIN_RICH_SEGMENT_KINDS.TTS]: RICH_SEGMENT_MODE.TEXT,
27
+ };
@@ -0,0 +1,11 @@
1
+ import type { MessageElement } from '../../types.js';
2
+ import type { RichSegmentRenderContext, RichSegmentRenderResult } from './types.js';
3
+ export declare abstract class RichSegment<TData> {
4
+ readonly data: TData;
5
+ abstract readonly segmentType: string;
6
+ constructor(data: TData);
7
+ abstract render(mode: string, ctx?: RichSegmentRenderContext): Promise<RichSegmentRenderResult>;
8
+ toJSON(): MessageElement;
9
+ }
10
+ export declare function isRichSegment(item: unknown): item is RichSegment<unknown>;
11
+ export declare function richSegmentKind(item: MessageElement | string): string | null;
@@ -0,0 +1,24 @@
1
+ import { richSegmentRegistry } from './registry.js';
2
+ export class RichSegment {
3
+ data;
4
+ constructor(data) {
5
+ this.data = data;
6
+ }
7
+ toJSON() {
8
+ return { type: this.segmentType, data: this.data };
9
+ }
10
+ }
11
+ export function isRichSegment(item) {
12
+ return item instanceof RichSegment;
13
+ }
14
+ export function richSegmentKind(item) {
15
+ if (typeof item === 'string')
16
+ return null;
17
+ const type = item.type;
18
+ if (typeof type !== 'string')
19
+ return null;
20
+ if (richSegmentRegistry.has(type)) {
21
+ return type;
22
+ }
23
+ return null;
24
+ }
@@ -0,0 +1,4 @@
1
+ /** 内置 kind 的默认出站 policy(由 registry 生成,增 kind 时自动包含) */
2
+ export declare const DEFAULT_OUTBOUND_RICH_SEGMENT_POLICY: import("./types.js").OutboundRichSegmentPolicy;
3
+ /** 测试:清空 registry 后重新注册内置 kind */
4
+ export declare function resetBuiltinRichSegmentKindsForTests(): void;
@@ -0,0 +1,40 @@
1
+ import { registerRichSegmentKind, richSegmentRegistry } from './registry.js';
2
+ import { wrapQrcodeSegment } from './qrcode-segment.js';
3
+ import { wrapHtmlSegment } from './html-segment.js';
4
+ import { wrapMarkdownSegment } from './markdown-segment.js';
5
+ import { wrapTtsSegment } from './tts-segment.js';
6
+ import { BUILTIN_RICH_SEGMENT_KINDS, RICH_SEGMENT_MODE } from './types.js';
7
+ function registerBuiltinRichSegmentKinds() {
8
+ registerRichSegmentKind({
9
+ kind: BUILTIN_RICH_SEGMENT_KINDS.QRCODE,
10
+ defaultMode: RICH_SEGMENT_MODE.IMAGE,
11
+ modes: [RICH_SEGMENT_MODE.IMAGE, RICH_SEGMENT_MODE.TEXT, RICH_SEGMENT_MODE.ORIGIN],
12
+ wrap: wrapQrcodeSegment,
13
+ });
14
+ registerRichSegmentKind({
15
+ kind: BUILTIN_RICH_SEGMENT_KINDS.HTML,
16
+ defaultMode: RICH_SEGMENT_MODE.TEXT,
17
+ modes: [RICH_SEGMENT_MODE.IMAGE, RICH_SEGMENT_MODE.TEXT, RICH_SEGMENT_MODE.ORIGIN],
18
+ wrap: wrapHtmlSegment,
19
+ });
20
+ registerRichSegmentKind({
21
+ kind: BUILTIN_RICH_SEGMENT_KINDS.MARKDOWN,
22
+ defaultMode: RICH_SEGMENT_MODE.TEXT,
23
+ modes: [RICH_SEGMENT_MODE.IMAGE, RICH_SEGMENT_MODE.TEXT, RICH_SEGMENT_MODE.ORIGIN],
24
+ wrap: wrapMarkdownSegment,
25
+ });
26
+ registerRichSegmentKind({
27
+ kind: BUILTIN_RICH_SEGMENT_KINDS.TTS,
28
+ defaultMode: RICH_SEGMENT_MODE.AUDIO,
29
+ modes: [RICH_SEGMENT_MODE.ORIGIN, RICH_SEGMENT_MODE.AUDIO, RICH_SEGMENT_MODE.TEXT],
30
+ wrap: wrapTtsSegment,
31
+ });
32
+ }
33
+ registerBuiltinRichSegmentKinds();
34
+ /** 内置 kind 的默认出站 policy(由 registry 生成,增 kind 时自动包含) */
35
+ export const DEFAULT_OUTBOUND_RICH_SEGMENT_POLICY = richSegmentRegistry.buildDefaultPolicy();
36
+ /** 测试:清空 registry 后重新注册内置 kind */
37
+ export function resetBuiltinRichSegmentKindsForTests() {
38
+ richSegmentRegistry.clearForTests();
39
+ registerBuiltinRichSegmentKinds();
40
+ }
@@ -0,0 +1,6 @@
1
+ import type { RichSegmentCapabilityLoader, RichSegmentCapabilityLoaderOptions, RichSegmentRenderContext } from './types.js';
2
+ /** 注册 optional 包能力(如 html-renderer、未来 media-pipeline) */
3
+ export declare function registerRichSegmentCapabilityLoader(id: string, loader: RichSegmentCapabilityLoader): void;
4
+ /** 测试隔离 */
5
+ export declare function resetRichSegmentCapabilityLoadersForTests(): void;
6
+ export declare function createRichSegmentRenderContext(options?: RichSegmentCapabilityLoaderOptions): RichSegmentRenderContext;
@@ -0,0 +1,39 @@
1
+ import { loadHtmlRenderer } from '../html-renderer-loader.js';
2
+ import { loadSpeechPipeline } from '../speech-loader.js';
3
+ const capabilityLoaders = new Map();
4
+ /** 注册 optional 包能力(如 html-renderer、未来 media-pipeline) */
5
+ export function registerRichSegmentCapabilityLoader(id, loader) {
6
+ capabilityLoaders.set(id, loader);
7
+ }
8
+ /** 测试隔离 */
9
+ export function resetRichSegmentCapabilityLoadersForTests() {
10
+ capabilityLoaders.clear();
11
+ registerCoreRichSegmentCapabilityLoaders();
12
+ }
13
+ function registerCoreRichSegmentCapabilityLoaders() {
14
+ registerRichSegmentCapabilityLoader('html-renderer', async (options) => loadHtmlRenderer({
15
+ getConfig: options.getConfig,
16
+ warn: options.warn,
17
+ }));
18
+ registerRichSegmentCapabilityLoader('speech', async (options) => loadSpeechPipeline({
19
+ getConfig: options.getConfig,
20
+ warn: options.warn,
21
+ }));
22
+ }
23
+ registerCoreRichSegmentCapabilityLoaders();
24
+ export function createRichSegmentRenderContext(options = {}) {
25
+ const cache = new Map();
26
+ const resolveCapability = async (id) => {
27
+ if (!cache.has(id)) {
28
+ const loader = capabilityLoaders.get(id);
29
+ cache.set(id, loader ? loader(options) : Promise.resolve(undefined));
30
+ }
31
+ return cache.get(id);
32
+ };
33
+ return {
34
+ resolveCapability,
35
+ getHtmlRenderer: () => resolveCapability('html-renderer'),
36
+ warn: options.warn,
37
+ logContentChain: options.logContentChain,
38
+ };
39
+ }
@@ -0,0 +1,15 @@
1
+ import { RichSegment } from './base.js';
2
+ import { type RichSegmentRenderContext, type RichSegmentRenderResult } from './types.js';
3
+ export interface HtmlSegmentData {
4
+ html: string;
5
+ text?: string;
6
+ width?: number;
7
+ backgroundColor?: string;
8
+ fileName?: string;
9
+ }
10
+ export declare class HtmlSegment extends RichSegment<HtmlSegmentData> {
11
+ readonly segmentType: "html";
12
+ readonly type: "html";
13
+ render(mode: string, ctx?: RichSegmentRenderContext): Promise<RichSegmentRenderResult>;
14
+ }
15
+ export declare function wrapHtmlSegment(data: Record<string, unknown>): HtmlSegment;