@openclaw/line 2026.9.5 → 2026.9.7

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 (433) hide show
  1. package/assets/icon.png +0 -0
  2. package/dist/.setup/{accounts-BBEFMYbY.mjs → accounts-DOiM8-y3.mjs} +1 -4
  3. package/dist/.setup/api-4RgpQmHW.mjs +3 -0
  4. package/dist/.setup/{api-W3zy11mj.mjs → api-w4QdlCCB.mjs} +2 -2
  5. package/dist/.setup/{card-command-PSnrhetp.mjs → card-command-DYf4gnmI.mjs} +25 -33
  6. package/dist/.setup/{channel-CAFu4vuW.mjs → channel-DN6Za8Vm.mjs} +789 -26
  7. package/dist/.setup/channel.runtime-bd5vGeSo.mjs +4 -0
  8. package/dist/.setup/{monitor-1JaX1WOU.mjs → monitor-C01hAm3f.mjs} +268 -340
  9. package/dist/.setup/monitor.runtime-DwH2zK48.mjs +2 -0
  10. package/dist/.setup/outbound.runtime-D_Gs99Dm.mjs +3 -0
  11. package/dist/.setup/probe.runtime-Cj08-BZ1.mjs +2 -0
  12. package/dist/.setup/runtime-V7yh9OeC.mjs +8 -0
  13. package/dist/.setup/{send-E6GiL_tr.mjs → send-DOY1WTxv.mjs} +7 -26
  14. package/dist/.setup/{send-retry-DaGwYlBO.mjs → send-retry-DV6I0muq.mjs} +105 -209
  15. package/dist/.setup/{setup-surface-CcfKJKtr.mjs → setup-surface-CbfkmkIS.mjs} +15 -4
  16. package/dist/.setup/{markdown-to-line-Dvyr_6HD.mjs → template-messages-CxCnYsWN.mjs} +168 -189
  17. package/dist/api.js +2 -2
  18. package/dist/channel-plugin-api.js +1 -1
  19. package/dist/contract-api.js +1 -1
  20. package/dist/index.js +1 -1
  21. package/dist/runtime-api.js +2 -260
  22. package/dist/setup-api.js +1 -1
  23. package/dist/setup-entry.js +1 -1
  24. package/node_modules/@line/bot-sdk/node_modules/@types/node/README.md +1 -1
  25. package/node_modules/@line/bot-sdk/node_modules/@types/node/child_process.d.ts +1 -1
  26. package/node_modules/@line/bot-sdk/node_modules/@types/node/package.json +2 -2
  27. package/node_modules/@line/bot-sdk/node_modules/@types/node/stream/web.d.ts +4 -0
  28. package/node_modules/typebox/build/compile/code.mjs +1 -2
  29. package/node_modules/typebox/build/compile/validator.mjs +5 -1
  30. package/node_modules/typebox/build/format/iri.mjs +16 -9
  31. package/node_modules/typebox/build/guard/emit.mjs +2 -2
  32. package/node_modules/typebox/build/guard/guard.d.mts +7 -5
  33. package/node_modules/typebox/build/guard/guard.mjs +14 -9
  34. package/node_modules/typebox/build/guard/index.mjs +6 -0
  35. package/node_modules/typebox/build/guard/unicode/unicode.d.mts +6 -0
  36. package/node_modules/typebox/build/guard/unicode/unicode.mjs +35 -0
  37. package/node_modules/typebox/build/guard/{string.mjs → unicode/unicode_segment.mjs} +16 -19
  38. package/node_modules/typebox/build/schema/build.mjs +2 -3
  39. package/node_modules/typebox/build/schema/engine/_pathing.d.mts +1 -0
  40. package/node_modules/typebox/build/schema/engine/_pathing.mjs +11 -0
  41. package/node_modules/typebox/build/schema/engine/_refine.mjs +13 -5
  42. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +2 -1
  43. package/node_modules/typebox/build/schema/engine/dependencies.mjs +2 -1
  44. package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +2 -1
  45. package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +1 -1
  46. package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +2 -2
  47. package/node_modules/typebox/build/schema/engine/format.mjs +9 -2
  48. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +3 -2
  49. package/node_modules/typebox/build/schema/engine/properties.mjs +3 -2
  50. package/node_modules/typebox/build/schema/engine/propertyNames.mjs +2 -1
  51. package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +1 -1
  52. package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +2 -2
  53. package/node_modules/typebox/build/schema/engine/ref.d.mts +1 -1
  54. package/node_modules/typebox/build/schema/engine/ref.mjs +2 -2
  55. package/node_modules/typebox/build/schema/engine/schema.mjs +24 -24
  56. package/node_modules/typebox/build/schema/parse.mjs +3 -0
  57. package/node_modules/typebox/build/schema/pointer/pointer.d.mts +1 -6
  58. package/node_modules/typebox/build/schema/pointer/pointer.mjs +47 -64
  59. package/node_modules/typebox/build/system/settings/internal.d.mts +2 -0
  60. package/node_modules/typebox/build/system/settings/internal.mjs +20 -0
  61. package/node_modules/typebox/build/system/settings/settings.d.mts +11 -0
  62. package/node_modules/typebox/build/system/settings/settings.mjs +14 -0
  63. package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
  64. package/node_modules/typebox/build/type/extends/inference.mjs +15 -2
  65. package/node_modules/typebox/build/type/extends/tuple.d.mts +2 -1
  66. package/node_modules/typebox/build/type/extends/tuple.mjs +21 -1
  67. package/node_modules/typebox/build/value/parse/parse.mjs +10 -4
  68. package/node_modules/typebox/package.json +1 -1
  69. package/node_modules/typebox/readme.md +3 -1
  70. package/node_modules/zod/README.md +2 -2
  71. package/node_modules/zod/compile.cjs +19 -0
  72. package/node_modules/zod/index.cjs +19 -0
  73. package/node_modules/zod/locales/index.cjs +19 -0
  74. package/node_modules/zod/mini/index.cjs +19 -0
  75. package/node_modules/zod/package.json +8 -7
  76. package/node_modules/zod/src/v3/helpers/errorUtil.ts +1 -1
  77. package/node_modules/zod/src/v4/classic/external.ts +2 -0
  78. package/node_modules/zod/src/v4/classic/from-json-schema.ts +248 -25
  79. package/node_modules/zod/src/v4/classic/schemas.ts +243 -168
  80. package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +60 -9
  81. package/node_modules/zod/src/v4/classic/tests/bigint.test.ts +6 -0
  82. package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +2 -2
  83. package/node_modules/zod/src/v4/classic/tests/cyclic-data.test.ts +265 -0
  84. package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +112 -6
  85. package/node_modules/zod/src/v4/classic/tests/enum.test.ts +9 -0
  86. package/node_modules/zod/src/v4/classic/tests/error.test.ts +130 -1
  87. package/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +157 -0
  88. package/node_modules/zod/src/v4/classic/tests/iban.test.ts +81 -0
  89. package/node_modules/zod/src/v4/classic/tests/instance-footprint.test.ts +40 -2
  90. package/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +27 -7
  91. package/node_modules/zod/src/v4/classic/tests/issue-schema.test.ts +88 -56
  92. package/node_modules/zod/src/v4/classic/tests/number.test.ts +39 -0
  93. package/node_modules/zod/src/v4/classic/tests/object.test.ts +56 -0
  94. package/node_modules/zod/src/v4/classic/tests/optin-ladder.test.ts +3 -2
  95. package/node_modules/zod/src/v4/classic/tests/prefault.test.ts +70 -0
  96. package/node_modules/zod/src/v4/classic/tests/properties.test.ts +141 -0
  97. package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +46 -1
  98. package/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +19 -0
  99. package/node_modules/zod/src/v4/classic/tests/string.test.ts +95 -1
  100. package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +33 -1
  101. package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +234 -38
  102. package/node_modules/zod/src/v4/classic/tests/validate.test.ts +569 -0
  103. package/node_modules/zod/src/v4/core/api.ts +44 -28
  104. package/node_modules/zod/src/v4/core/checks.ts +62 -102
  105. package/node_modules/zod/src/v4/core/compile.ts +218 -93
  106. package/node_modules/zod/src/v4/core/core.ts +1 -3
  107. package/node_modules/zod/src/v4/core/doc.ts +6 -2
  108. package/node_modules/zod/src/v4/core/errors.ts +3 -6
  109. package/node_modules/zod/src/v4/core/json-schema-generator.ts +2 -2
  110. package/node_modules/zod/src/v4/core/json-schema-processors.ts +185 -81
  111. package/node_modules/zod/src/v4/core/memoizer.ts +75 -28
  112. package/node_modules/zod/src/v4/core/parse.ts +37 -16
  113. package/node_modules/zod/src/v4/core/regexes.ts +14 -4
  114. package/node_modules/zod/src/v4/core/schemas.ts +296 -132
  115. package/node_modules/zod/src/v4/core/tests/cached.test.ts +54 -0
  116. package/node_modules/zod/src/v4/core/tests/compile-differential.test.ts +35 -0
  117. package/node_modules/zod/src/v4/core/tests/compile-generative.test.ts +445 -0
  118. package/node_modules/zod/src/v4/core/tests/compile.test.ts +399 -2
  119. package/node_modules/zod/src/v4/core/tests/email-regex.test.ts +140 -0
  120. package/node_modules/zod/src/v4/core/tests/locales/tg.test.ts +85 -0
  121. package/node_modules/zod/src/v4/core/tests/polyfill-collision.test.ts +46 -0
  122. package/node_modules/zod/src/v4/core/tests/url-no-canparse.test.ts +118 -16
  123. package/node_modules/zod/src/v4/core/to-json-schema.ts +9 -7
  124. package/node_modules/zod/src/v4/core/util.ts +218 -147
  125. package/node_modules/zod/src/v4/core/versions.ts +2 -2
  126. package/node_modules/zod/src/v4/locales/ar.ts +2 -0
  127. package/node_modules/zod/src/v4/locales/az.ts +2 -0
  128. package/node_modules/zod/src/v4/locales/be.ts +2 -0
  129. package/node_modules/zod/src/v4/locales/bg.ts +2 -0
  130. package/node_modules/zod/src/v4/locales/bn.ts +2 -0
  131. package/node_modules/zod/src/v4/locales/ca.ts +2 -0
  132. package/node_modules/zod/src/v4/locales/ckb.ts +2 -0
  133. package/node_modules/zod/src/v4/locales/cs.ts +2 -0
  134. package/node_modules/zod/src/v4/locales/da.ts +2 -0
  135. package/node_modules/zod/src/v4/locales/de.ts +2 -0
  136. package/node_modules/zod/src/v4/locales/el.ts +2 -0
  137. package/node_modules/zod/src/v4/locales/en.ts +2 -0
  138. package/node_modules/zod/src/v4/locales/eo.ts +2 -0
  139. package/node_modules/zod/src/v4/locales/es.ts +2 -0
  140. package/node_modules/zod/src/v4/locales/fa.ts +2 -0
  141. package/node_modules/zod/src/v4/locales/fi.ts +2 -0
  142. package/node_modules/zod/src/v4/locales/fr-CA.ts +2 -0
  143. package/node_modules/zod/src/v4/locales/fr.ts +2 -0
  144. package/node_modules/zod/src/v4/locales/gu.ts +2 -0
  145. package/node_modules/zod/src/v4/locales/he.ts +2 -0
  146. package/node_modules/zod/src/v4/locales/hi.ts +2 -0
  147. package/node_modules/zod/src/v4/locales/hr.ts +2 -0
  148. package/node_modules/zod/src/v4/locales/hu.ts +2 -0
  149. package/node_modules/zod/src/v4/locales/hy.ts +2 -0
  150. package/node_modules/zod/src/v4/locales/id.ts +2 -0
  151. package/node_modules/zod/src/v4/locales/index.ts +1 -0
  152. package/node_modules/zod/src/v4/locales/is.ts +2 -0
  153. package/node_modules/zod/src/v4/locales/it.ts +2 -0
  154. package/node_modules/zod/src/v4/locales/ja.ts +2 -0
  155. package/node_modules/zod/src/v4/locales/ka.ts +2 -0
  156. package/node_modules/zod/src/v4/locales/km.ts +2 -0
  157. package/node_modules/zod/src/v4/locales/kn.ts +2 -0
  158. package/node_modules/zod/src/v4/locales/ko.ts +2 -0
  159. package/node_modules/zod/src/v4/locales/lt.ts +2 -0
  160. package/node_modules/zod/src/v4/locales/mk.ts +2 -0
  161. package/node_modules/zod/src/v4/locales/ms.ts +2 -0
  162. package/node_modules/zod/src/v4/locales/ne.ts +2 -0
  163. package/node_modules/zod/src/v4/locales/nl.ts +2 -0
  164. package/node_modules/zod/src/v4/locales/nn.ts +2 -0
  165. package/node_modules/zod/src/v4/locales/no.ts +2 -0
  166. package/node_modules/zod/src/v4/locales/ota.ts +2 -0
  167. package/node_modules/zod/src/v4/locales/pl.ts +2 -0
  168. package/node_modules/zod/src/v4/locales/ps.ts +2 -0
  169. package/node_modules/zod/src/v4/locales/pt-BR.ts +2 -0
  170. package/node_modules/zod/src/v4/locales/pt.ts +2 -0
  171. package/node_modules/zod/src/v4/locales/ro.ts +2 -0
  172. package/node_modules/zod/src/v4/locales/ru.ts +2 -0
  173. package/node_modules/zod/src/v4/locales/sk.ts +2 -0
  174. package/node_modules/zod/src/v4/locales/sl.ts +2 -0
  175. package/node_modules/zod/src/v4/locales/sv.ts +2 -0
  176. package/node_modules/zod/src/v4/locales/ta.ts +2 -0
  177. package/node_modules/zod/src/v4/locales/tg.ts +135 -0
  178. package/node_modules/zod/src/v4/locales/th.ts +2 -0
  179. package/node_modules/zod/src/v4/locales/tk.ts +2 -0
  180. package/node_modules/zod/src/v4/locales/tr.ts +2 -0
  181. package/node_modules/zod/src/v4/locales/uk.ts +2 -0
  182. package/node_modules/zod/src/v4/locales/ur.ts +2 -0
  183. package/node_modules/zod/src/v4/locales/uz.ts +2 -0
  184. package/node_modules/zod/src/v4/locales/vi.ts +2 -0
  185. package/node_modules/zod/src/v4/locales/yo.ts +2 -0
  186. package/node_modules/zod/src/v4/locales/zh-CN.ts +2 -0
  187. package/node_modules/zod/src/v4/locales/zh-TW.ts +2 -0
  188. package/node_modules/zod/src/v4/mini/external.ts +2 -0
  189. package/node_modules/zod/src/v4/mini/schemas.ts +32 -7
  190. package/node_modules/zod/src/v4/mini/tests/checks.test.ts +1 -1
  191. package/node_modules/zod/src/v4/mini/tests/computed.test.ts +11 -17
  192. package/node_modules/zod/src/v4/mini/tests/index.test.ts +86 -0
  193. package/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +16 -0
  194. package/node_modules/zod/src/v4/mini/tests/string.test.ts +23 -0
  195. package/node_modules/zod/v3/ZodError.cjs +19 -0
  196. package/node_modules/zod/v3/errors.cjs +19 -0
  197. package/node_modules/zod/v3/external.cjs +19 -0
  198. package/node_modules/zod/v3/helpers/enumUtil.cjs +19 -0
  199. package/node_modules/zod/v3/helpers/errorUtil.cjs +20 -1
  200. package/node_modules/zod/v3/helpers/errorUtil.js +1 -1
  201. package/node_modules/zod/v3/helpers/parseUtil.cjs +19 -0
  202. package/node_modules/zod/v3/helpers/partialUtil.cjs +19 -0
  203. package/node_modules/zod/v3/helpers/typeAliases.cjs +19 -0
  204. package/node_modules/zod/v3/helpers/util.cjs +19 -0
  205. package/node_modules/zod/v3/index.cjs +19 -0
  206. package/node_modules/zod/v3/standard-schema.cjs +19 -0
  207. package/node_modules/zod/v3/types.cjs +19 -0
  208. package/node_modules/zod/v4/classic/checks.cjs +19 -0
  209. package/node_modules/zod/v4/classic/coerce.cjs +19 -0
  210. package/node_modules/zod/v4/classic/compat.cjs +19 -0
  211. package/node_modules/zod/v4/classic/deep-partial.cjs +19 -0
  212. package/node_modules/zod/v4/classic/errors.cjs +19 -0
  213. package/node_modules/zod/v4/classic/external.cjs +22 -1
  214. package/node_modules/zod/v4/classic/external.d.cts +1 -1
  215. package/node_modules/zod/v4/classic/external.d.ts +1 -1
  216. package/node_modules/zod/v4/classic/external.js +1 -1
  217. package/node_modules/zod/v4/classic/from-json-schema.cjs +264 -24
  218. package/node_modules/zod/v4/classic/from-json-schema.js +245 -24
  219. package/node_modules/zod/v4/classic/in-out.cjs +19 -0
  220. package/node_modules/zod/v4/classic/index.cjs +19 -0
  221. package/node_modules/zod/v4/classic/iso.cjs +19 -0
  222. package/node_modules/zod/v4/classic/parse.cjs +19 -0
  223. package/node_modules/zod/v4/classic/schemas.cjs +100 -35
  224. package/node_modules/zod/v4/classic/schemas.d.cts +15 -1
  225. package/node_modules/zod/v4/classic/schemas.d.ts +15 -1
  226. package/node_modules/zod/v4/classic/schemas.js +77 -33
  227. package/node_modules/zod/v4/core/api.cjs +45 -22
  228. package/node_modules/zod/v4/core/api.d.cts +12 -6
  229. package/node_modules/zod/v4/core/api.d.ts +12 -6
  230. package/node_modules/zod/v4/core/api.js +25 -22
  231. package/node_modules/zod/v4/core/checks.cjs +51 -97
  232. package/node_modules/zod/v4/core/checks.d.cts +17 -1
  233. package/node_modules/zod/v4/core/checks.d.ts +17 -1
  234. package/node_modules/zod/v4/core/checks.js +31 -96
  235. package/node_modules/zod/v4/core/compile.cjs +173 -78
  236. package/node_modules/zod/v4/core/compile.d.cts +18 -4
  237. package/node_modules/zod/v4/core/compile.d.ts +18 -4
  238. package/node_modules/zod/v4/core/compile.js +154 -79
  239. package/node_modules/zod/v4/core/core.cjs +20 -1
  240. package/node_modules/zod/v4/core/core.js +1 -1
  241. package/node_modules/zod/v4/core/doc.cjs +26 -2
  242. package/node_modules/zod/v4/core/doc.js +7 -2
  243. package/node_modules/zod/v4/core/errors.cjs +21 -5
  244. package/node_modules/zod/v4/core/errors.js +2 -5
  245. package/node_modules/zod/v4/core/index.cjs +19 -0
  246. package/node_modules/zod/v4/core/json-schema-generator.cjs +20 -1
  247. package/node_modules/zod/v4/core/json-schema-generator.js +2 -2
  248. package/node_modules/zod/v4/core/json-schema-processors.cjs +188 -72
  249. package/node_modules/zod/v4/core/json-schema-processors.d.cts +16 -0
  250. package/node_modules/zod/v4/core/json-schema-processors.d.ts +16 -0
  251. package/node_modules/zod/v4/core/json-schema-processors.js +170 -74
  252. package/node_modules/zod/v4/core/json-schema.cjs +19 -0
  253. package/node_modules/zod/v4/core/memoizer.cjs +111 -23
  254. package/node_modules/zod/v4/core/memoizer.js +69 -23
  255. package/node_modules/zod/v4/core/parse.cjs +56 -16
  256. package/node_modules/zod/v4/core/parse.js +37 -16
  257. package/node_modules/zod/v4/core/regexes.cjs +31 -6
  258. package/node_modules/zod/v4/core/regexes.d.cts +3 -0
  259. package/node_modules/zod/v4/core/regexes.d.ts +3 -0
  260. package/node_modules/zod/v4/core/regexes.js +10 -4
  261. package/node_modules/zod/v4/core/registries.cjs +19 -0
  262. package/node_modules/zod/v4/core/schemas.cjs +302 -114
  263. package/node_modules/zod/v4/core/schemas.d.cts +28 -8
  264. package/node_modules/zod/v4/core/schemas.d.ts +28 -8
  265. package/node_modules/zod/v4/core/schemas.js +279 -113
  266. package/node_modules/zod/v4/core/standard-schema.cjs +19 -0
  267. package/node_modules/zod/v4/core/to-json-schema.cjs +28 -7
  268. package/node_modules/zod/v4/core/to-json-schema.d.cts +4 -3
  269. package/node_modules/zod/v4/core/to-json-schema.d.ts +4 -3
  270. package/node_modules/zod/v4/core/to-json-schema.js +7 -6
  271. package/node_modules/zod/v4/core/util.cjs +177 -143
  272. package/node_modules/zod/v4/core/util.d.cts +25 -4
  273. package/node_modules/zod/v4/core/util.d.ts +25 -4
  274. package/node_modules/zod/v4/core/util.js +156 -143
  275. package/node_modules/zod/v4/core/versions.cjs +21 -2
  276. package/node_modules/zod/v4/core/versions.d.cts +1 -1
  277. package/node_modules/zod/v4/core/versions.d.ts +1 -1
  278. package/node_modules/zod/v4/core/versions.js +2 -2
  279. package/node_modules/zod/v4/core/visit.cjs +19 -0
  280. package/node_modules/zod/v4/index.cjs +19 -0
  281. package/node_modules/zod/v4/locales/ar.cjs +2 -0
  282. package/node_modules/zod/v4/locales/ar.js +2 -0
  283. package/node_modules/zod/v4/locales/az.cjs +2 -0
  284. package/node_modules/zod/v4/locales/az.js +2 -0
  285. package/node_modules/zod/v4/locales/be.cjs +2 -0
  286. package/node_modules/zod/v4/locales/be.js +2 -0
  287. package/node_modules/zod/v4/locales/bg.cjs +2 -0
  288. package/node_modules/zod/v4/locales/bg.js +2 -0
  289. package/node_modules/zod/v4/locales/bn.cjs +2 -0
  290. package/node_modules/zod/v4/locales/bn.js +2 -0
  291. package/node_modules/zod/v4/locales/ca.cjs +2 -0
  292. package/node_modules/zod/v4/locales/ca.js +2 -0
  293. package/node_modules/zod/v4/locales/ckb.cjs +2 -0
  294. package/node_modules/zod/v4/locales/ckb.js +2 -0
  295. package/node_modules/zod/v4/locales/cs.cjs +2 -0
  296. package/node_modules/zod/v4/locales/cs.js +2 -0
  297. package/node_modules/zod/v4/locales/da.cjs +2 -0
  298. package/node_modules/zod/v4/locales/da.js +2 -0
  299. package/node_modules/zod/v4/locales/de.cjs +2 -0
  300. package/node_modules/zod/v4/locales/de.js +2 -0
  301. package/node_modules/zod/v4/locales/el.cjs +2 -0
  302. package/node_modules/zod/v4/locales/el.js +2 -0
  303. package/node_modules/zod/v4/locales/en.cjs +2 -0
  304. package/node_modules/zod/v4/locales/en.js +2 -0
  305. package/node_modules/zod/v4/locales/eo.cjs +2 -0
  306. package/node_modules/zod/v4/locales/eo.js +2 -0
  307. package/node_modules/zod/v4/locales/es.cjs +2 -0
  308. package/node_modules/zod/v4/locales/es.js +2 -0
  309. package/node_modules/zod/v4/locales/fa.cjs +2 -0
  310. package/node_modules/zod/v4/locales/fa.js +2 -0
  311. package/node_modules/zod/v4/locales/fi.cjs +2 -0
  312. package/node_modules/zod/v4/locales/fi.js +2 -0
  313. package/node_modules/zod/v4/locales/fr-CA.cjs +2 -0
  314. package/node_modules/zod/v4/locales/fr-CA.js +2 -0
  315. package/node_modules/zod/v4/locales/fr.cjs +2 -0
  316. package/node_modules/zod/v4/locales/fr.js +2 -0
  317. package/node_modules/zod/v4/locales/gu.cjs +2 -0
  318. package/node_modules/zod/v4/locales/gu.js +2 -0
  319. package/node_modules/zod/v4/locales/he.cjs +2 -0
  320. package/node_modules/zod/v4/locales/he.js +2 -0
  321. package/node_modules/zod/v4/locales/hi.cjs +2 -0
  322. package/node_modules/zod/v4/locales/hi.js +2 -0
  323. package/node_modules/zod/v4/locales/hr.cjs +2 -0
  324. package/node_modules/zod/v4/locales/hr.js +2 -0
  325. package/node_modules/zod/v4/locales/hu.cjs +2 -0
  326. package/node_modules/zod/v4/locales/hu.js +2 -0
  327. package/node_modules/zod/v4/locales/hy.cjs +2 -0
  328. package/node_modules/zod/v4/locales/hy.js +2 -0
  329. package/node_modules/zod/v4/locales/id.cjs +2 -0
  330. package/node_modules/zod/v4/locales/id.js +2 -0
  331. package/node_modules/zod/v4/locales/index.cjs +22 -1
  332. package/node_modules/zod/v4/locales/index.d.cts +1 -0
  333. package/node_modules/zod/v4/locales/index.d.ts +1 -0
  334. package/node_modules/zod/v4/locales/index.js +1 -0
  335. package/node_modules/zod/v4/locales/is.cjs +2 -0
  336. package/node_modules/zod/v4/locales/is.js +2 -0
  337. package/node_modules/zod/v4/locales/it.cjs +2 -0
  338. package/node_modules/zod/v4/locales/it.js +2 -0
  339. package/node_modules/zod/v4/locales/ja.cjs +2 -0
  340. package/node_modules/zod/v4/locales/ja.js +2 -0
  341. package/node_modules/zod/v4/locales/ka.cjs +2 -0
  342. package/node_modules/zod/v4/locales/ka.js +2 -0
  343. package/node_modules/zod/v4/locales/km.cjs +2 -0
  344. package/node_modules/zod/v4/locales/km.js +2 -0
  345. package/node_modules/zod/v4/locales/kn.cjs +2 -0
  346. package/node_modules/zod/v4/locales/kn.js +2 -0
  347. package/node_modules/zod/v4/locales/ko.cjs +2 -0
  348. package/node_modules/zod/v4/locales/ko.js +2 -0
  349. package/node_modules/zod/v4/locales/lt.cjs +2 -0
  350. package/node_modules/zod/v4/locales/lt.js +2 -0
  351. package/node_modules/zod/v4/locales/mk.cjs +2 -0
  352. package/node_modules/zod/v4/locales/mk.js +2 -0
  353. package/node_modules/zod/v4/locales/ms.cjs +2 -0
  354. package/node_modules/zod/v4/locales/ms.js +2 -0
  355. package/node_modules/zod/v4/locales/ne.cjs +2 -0
  356. package/node_modules/zod/v4/locales/ne.js +2 -0
  357. package/node_modules/zod/v4/locales/nl.cjs +2 -0
  358. package/node_modules/zod/v4/locales/nl.js +2 -0
  359. package/node_modules/zod/v4/locales/nn.cjs +2 -0
  360. package/node_modules/zod/v4/locales/nn.js +2 -0
  361. package/node_modules/zod/v4/locales/no.cjs +2 -0
  362. package/node_modules/zod/v4/locales/no.js +2 -0
  363. package/node_modules/zod/v4/locales/ota.cjs +2 -0
  364. package/node_modules/zod/v4/locales/ota.js +2 -0
  365. package/node_modules/zod/v4/locales/pl.cjs +2 -0
  366. package/node_modules/zod/v4/locales/pl.js +2 -0
  367. package/node_modules/zod/v4/locales/ps.cjs +2 -0
  368. package/node_modules/zod/v4/locales/ps.js +2 -0
  369. package/node_modules/zod/v4/locales/pt-BR.cjs +2 -0
  370. package/node_modules/zod/v4/locales/pt-BR.js +2 -0
  371. package/node_modules/zod/v4/locales/pt.cjs +2 -0
  372. package/node_modules/zod/v4/locales/pt.js +2 -0
  373. package/node_modules/zod/v4/locales/ro.cjs +2 -0
  374. package/node_modules/zod/v4/locales/ro.js +2 -0
  375. package/node_modules/zod/v4/locales/ru.cjs +2 -0
  376. package/node_modules/zod/v4/locales/ru.js +2 -0
  377. package/node_modules/zod/v4/locales/sk.cjs +2 -0
  378. package/node_modules/zod/v4/locales/sk.js +2 -0
  379. package/node_modules/zod/v4/locales/sl.cjs +2 -0
  380. package/node_modules/zod/v4/locales/sl.js +2 -0
  381. package/node_modules/zod/v4/locales/sv.cjs +2 -0
  382. package/node_modules/zod/v4/locales/sv.js +2 -0
  383. package/node_modules/zod/v4/locales/ta.cjs +2 -0
  384. package/node_modules/zod/v4/locales/ta.js +2 -0
  385. package/node_modules/zod/v4/locales/tg.cjs +144 -0
  386. package/node_modules/zod/v4/locales/tg.d.cts +5 -0
  387. package/node_modules/zod/v4/locales/tg.d.ts +4 -0
  388. package/node_modules/zod/v4/locales/tg.js +117 -0
  389. package/node_modules/zod/v4/locales/th.cjs +2 -0
  390. package/node_modules/zod/v4/locales/th.js +2 -0
  391. package/node_modules/zod/v4/locales/tk.cjs +2 -0
  392. package/node_modules/zod/v4/locales/tk.js +2 -0
  393. package/node_modules/zod/v4/locales/tr.cjs +2 -0
  394. package/node_modules/zod/v4/locales/tr.js +2 -0
  395. package/node_modules/zod/v4/locales/uk.cjs +2 -0
  396. package/node_modules/zod/v4/locales/uk.js +2 -0
  397. package/node_modules/zod/v4/locales/ur.cjs +2 -0
  398. package/node_modules/zod/v4/locales/ur.js +2 -0
  399. package/node_modules/zod/v4/locales/uz.cjs +2 -0
  400. package/node_modules/zod/v4/locales/uz.js +2 -0
  401. package/node_modules/zod/v4/locales/vi.cjs +2 -0
  402. package/node_modules/zod/v4/locales/vi.js +2 -0
  403. package/node_modules/zod/v4/locales/yo.cjs +2 -0
  404. package/node_modules/zod/v4/locales/yo.js +2 -0
  405. package/node_modules/zod/v4/locales/zh-CN.cjs +2 -0
  406. package/node_modules/zod/v4/locales/zh-CN.js +2 -0
  407. package/node_modules/zod/v4/locales/zh-TW.cjs +2 -0
  408. package/node_modules/zod/v4/locales/zh-TW.js +2 -0
  409. package/node_modules/zod/v4/mini/checks.cjs +19 -0
  410. package/node_modules/zod/v4/mini/coerce.cjs +19 -0
  411. package/node_modules/zod/v4/mini/deep-partial.cjs +19 -0
  412. package/node_modules/zod/v4/mini/external.cjs +22 -1
  413. package/node_modules/zod/v4/mini/external.d.cts +1 -1
  414. package/node_modules/zod/v4/mini/external.d.ts +1 -1
  415. package/node_modules/zod/v4/mini/external.js +1 -1
  416. package/node_modules/zod/v4/mini/in-out.cjs +19 -0
  417. package/node_modules/zod/v4/mini/index.cjs +19 -0
  418. package/node_modules/zod/v4/mini/iso.cjs +19 -0
  419. package/node_modules/zod/v4/mini/parse.cjs +19 -0
  420. package/node_modules/zod/v4/mini/schemas.cjs +44 -8
  421. package/node_modules/zod/v4/mini/schemas.d.cts +6 -1
  422. package/node_modules/zod/v4/mini/schemas.d.ts +6 -1
  423. package/node_modules/zod/v4/mini/schemas.js +21 -6
  424. package/node_modules/zod/v4-mini/index.cjs +19 -0
  425. package/package.json +6 -6
  426. package/dist/.setup/account-helpers-BSUyZwLm.mjs +0 -12
  427. package/dist/.setup/api-BePkCTWu.mjs +0 -3
  428. package/dist/.setup/channel.runtime-CgI6K6p-.mjs +0 -4
  429. package/dist/.setup/monitor.runtime-D2vNVJRD.mjs +0 -2
  430. package/dist/.setup/outbound.runtime-CyrwiL69.mjs +0 -3
  431. package/dist/.setup/probe.runtime-kp-FIW5_.mjs +0 -2
  432. package/dist/.setup/rich-messages-Cp77q9NY.mjs +0 -872
  433. /package/node_modules/typebox/build/guard/{string.d.mts → unicode/unicode_segment.d.mts} +0 -0
@@ -1,12 +1,15 @@
1
- import { i as resolveLineAccount, r as resolveDefaultLineAccountId } from "./accounts-BBEFMYbY.mjs";
2
- import { b as normalizeAllowFrom, c as resolveLineQuestionPostback, f as buildLineQuickReplyFallbackText, g as resolveLineGroupConfigEntry, i as prepareLineReplyPayload, n as createLineQuickReply, p as getLineRuntime, s as parseLineQuestionPostbackData, x as normalizeLineAllowEntry, y as firstDefined } from "./rich-messages-Cp77q9NY.mjs";
3
- import { D as recordLineQuoteToken, E as readLineQuoteToken, O as reportLineQuoteCarrierMissing, T as canCarryLineQuoteToken, j as buildLineMediaMessage, k as resolveLineQuoteToken, n as findLineHttpError, r as resolveLineNonDispatchRetryable, t as explainLineRefusal, w as applyLineQuoteToken } from "./send-retry-DaGwYlBO.mjs";
1
+ import { n as resolveDefaultLineAccountId, r as resolveLineAccount } from "./accounts-DOiM8-y3.mjs";
2
+ import { a as resolveLineQuestionPostback, c as normalizeLineAllowEntry, i as parseLineQuestionPostbackData, n as createLineQuickReply, o as buildLineQuickReplyFallbackText, r as prepareLineReplyPayload, s as resolveLineGroupConfigEntry } from "./channel-DN6Za8Vm.mjs";
3
+ import { t as getLineRuntime } from "./runtime-V7yh9OeC.mjs";
4
+ import { D as recordLineQuoteToken, E as readLineQuoteToken, O as reportLineQuoteCarrierMissing, T as canCarryLineQuoteToken, j as buildLineMediaMessage, k as resolveLineQuoteToken, n as findLineHttpError, r as resolveLineNonDispatchRetryable, t as explainLineRefusal, w as applyLineQuoteToken } from "./send-retry-DV6I0muq.mjs";
4
5
  import { a as eventIdFor, n as LINE_WEBHOOK_SPOOL_INVALID_PAYLOAD_MESSAGE, o as laneKeyFor, r as LineWebhookPayloadError, t as LINE_WEBHOOK_SPOOL_INVALID_EVENT_REASON } from "./webhook-spool-contract-1rY8OJw8.mjs";
5
- import { a as buildTemplateMessageFromPayload, r as processLineMessage } from "./markdown-to-line-Dvyr_6HD.mjs";
6
- import { _ as showLoadingAnimation, a as getLineGroupName, d as pushMessageLine, f as pushMessagesLine, h as replyMessageLine, n as createLocationMessage, o as getUserDisplayName, s as getUserProfile, t as createFlexMessage, v as quotesLineBotMessage } from "./send-E6GiL_tr.mjs";
6
+ import { a as getUserDisplayName, g as quotesLineBotMessage, h as showLoadingAnimation, i as getLineGroupName, l as pushMessageLine, n as createLocationMessage, o as getUserProfile, p as replyMessageLine, t as createFlexMessage, u as pushMessagesLine } from "./send-DOY1WTxv.mjs";
7
+ import { n as processLineMessage, t as buildTemplateMessageFromPayload } from "./template-messages-CxCnYsWN.mjs";
7
8
  import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
8
9
  import { resolveChannelGroupsConfigPath } from "openclaw/plugin-sdk/channel-policy";
9
10
  import { normalizeOptionalString, normalizeStringEntries, readNonEmptyStringPreservingWhitespace } from "openclaw/plugin-sdk/string-coerce-runtime";
11
+ import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
12
+ import { firstDefined } from "openclaw/plugin-sdk/allow-from";
10
13
  import { DEFAULT_INGRESS_ADOPTION_STALL_MS, DEFAULT_INGRESS_RETRY_MAX_ATTEMPTS, bindIngressLifecycleToReplyOptions, createChannelIngressMonitor, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
11
14
  import { buildChannelInboundEventContext, buildMentionRegexes, formatInboundEnvelope, formatInboundMediaUnavailableText, formatLocationText, hasFinalInboundReplyDispatch, implicitMentionKindWhen, isChannelPartialDeliveryError, logInboundDrop, matchesMentionPatterns, resolveInboundSessionEnvelopeContext, toInboundMediaFactsWithMetadata, toLocationContext } from "openclaw/plugin-sdk/channel-inbound";
12
15
  import { collectErrorGraphCandidates, extractErrorCode, formatErrorMessage, readErrorName, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
@@ -16,132 +19,29 @@ import { createNonExitingRuntime, danger, logVerbose, shouldLogVerbose, waitForA
16
19
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
17
20
  import { classifyTransientNetworkErrorCode } from "openclaw/plugin-sdk/retry-runtime";
18
21
  import { fetchWithRuntimeDispatcherOrMockedGlobal } from "openclaw/plugin-sdk/runtime-fetch";
19
- import { setTimeout as setTimeout$1 } from "node:timers/promises";
20
- import { MediaFetchError } from "openclaw/plugin-sdk/media-runtime";
21
- import { saveMediaStream } from "openclaw/plugin-sdk/media-store";
22
+ import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
22
23
  import crypto from "node:crypto";
23
24
  import { recordChannelActivity } from "openclaw/plugin-sdk/channel-activity-runtime";
24
25
  import { resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
25
26
  import { channelReadyPatch, channelStoppedPatch } from "openclaw/plugin-sdk/gateway-runtime";
26
27
  import { canonicalizeWebhookRouteKey, registerWebhookTargetWithPluginRoute, resolveSingleWebhookTarget, resolveWebhookPath } from "openclaw/plugin-sdk/webhook-ingress";
27
28
  import { beginWebhookRequestPipelineOrReject, createWebhookInFlightLimiter, isRequestBodyLimitError, readRequestBodyWithLimit, requestBodyErrorToText, runDetachedWebhookWork, sendHttpRequestRejection } from "openclaw/plugin-sdk/webhook-request-guards";
28
- import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
29
29
  import { chunkMarkdownText } from "openclaw/plugin-sdk/reply-runtime";
30
- import { DEFAULT_GROUP_HISTORY_LIMIT, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
30
+ import { resolvePromptHistoryLimit } from "openclaw/plugin-sdk/number-runtime";
31
31
  import { getRuntimeConfig, getRuntimeConfigSnapshot, getRuntimeConfigSourceSnapshot, selectApplicableRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
32
- import { fanInChannelIngressLifecycles, resolveChannelImplicitMentions, resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
32
+ import { fanInChannelIngressLifecycles, resolveChannelImplicitMentions } from "openclaw/plugin-sdk/channel-ingress-runtime";
33
33
  import { reportChannelRoomJoin } from "openclaw/plugin-sdk/channel-join-intro-runtime";
34
34
  import { hasControlCommand } from "openclaw/plugin-sdk/command-auth-native";
35
- import { ensureConfiguredBindingRouteReady, readChannelAllowFromStore, resolveConfiguredBindingRoute, resolvePairingIdLabel, resolvePinnedMainDmOwnerFromAllowlist, resolveRuntimeConversationBindingRoute, upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
36
- import { resolveAgentRoute, resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
35
+ import { ensureConfiguredBindingRouteReady, readChannelAllowFromStore, resolveConfiguredBindingRoute, resolvePairingIdLabel, resolvePinnedMainDmOwnerFromAllowlist, upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
36
+ import { DEFAULT_GROUP_HISTORY_LIMIT, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
37
+ import { parseAgentSessionKey, resolveAgentRoute, resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
37
38
  import { resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
39
+ import { getSessionBindingService, inspectRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-binding-runtime";
40
+ import { setTimeout as setTimeout$1 } from "node:timers/promises";
41
+ import { MediaFetchError } from "openclaw/plugin-sdk/media-runtime";
42
+ import { saveMediaStream } from "openclaw/plugin-sdk/media-store";
38
43
  import { enqueueKeyedTask } from "openclaw/plugin-sdk/keyed-async-queue";
39
44
  import { safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
40
- //#region extensions/line/src/download.ts
41
- const CONTENT_READY_MAX_ATTEMPTS = 6;
42
- const CONTENT_READY_BASE_DELAY_MS = 500;
43
- const CONTENT_READY_MAX_DELAY_MS = 4e3;
44
- const CONTENT_DOWNLOAD_TIMEOUT_MS = 15e3;
45
- const LINE_CONTENT_BASE_URL = "https://api-data.line.me/v2/bot/message";
46
- var RetryableLineMediaFetchError = class extends MediaFetchError {
47
- constructor(message, options) {
48
- super("fetch_failed", message, options);
49
- this.name = "RetryableLineMediaFetchError";
50
- }
51
- };
52
- function contentBackoffDelayMs(attempt) {
53
- return Math.min(CONTENT_READY_BASE_DELAY_MS * 2 ** attempt, CONTENT_READY_MAX_DELAY_MS);
54
- }
55
- function lineContentUrl(messageId) {
56
- return `${LINE_CONTENT_BASE_URL}/${encodeURIComponent(messageId)}/content`;
57
- }
58
- async function* lineResponseBodyChunks(response, messageId, signal, onComplete) {
59
- const body = response.body;
60
- if (!body) throw new RetryableLineMediaFetchError(`LINE media response for message ${messageId} had no body`);
61
- const reader = body.getReader();
62
- let completed = false;
63
- try {
64
- while (true) {
65
- let chunk;
66
- try {
67
- chunk = await reader.read();
68
- } catch (err) {
69
- if (signal.aborted) throw signal.reason;
70
- throw new RetryableLineMediaFetchError(`LINE media response stream failed for message ${messageId}`, { cause: err });
71
- }
72
- if (chunk.done) {
73
- completed = true;
74
- onComplete();
75
- return;
76
- }
77
- if (chunk.value.byteLength > 0) yield chunk.value;
78
- }
79
- } finally {
80
- if (!completed) await reader.cancel(signal.aborted ? signal.reason : void 0).catch(() => void 0);
81
- try {
82
- reader.releaseLock();
83
- } catch {}
84
- }
85
- }
86
- async function fetchLineContentWhenReady(messageId, channelAccessToken, signal) {
87
- try {
88
- for (let attempt = 0; attempt < CONTENT_READY_MAX_ATTEMPTS; attempt++) {
89
- const response = await fetchWithRuntimeDispatcherOrMockedGlobal(lineContentUrl(messageId), {
90
- headers: { Authorization: `Bearer ${channelAccessToken}` },
91
- redirect: "error",
92
- signal
93
- });
94
- if (response.status === 200) {
95
- if (!response.body) throw new RetryableLineMediaFetchError(`LINE media response for message ${messageId} had no body`);
96
- return response;
97
- }
98
- await response.body?.cancel().catch(() => void 0);
99
- if (response.status !== 202) throw new MediaFetchError("http_error", `LINE media download failed for message ${messageId} (HTTP ${response.status})`, { status: response.status });
100
- if (attempt < 5) await setTimeout$1(contentBackoffDelayMs(attempt), void 0, { signal });
101
- }
102
- } catch (err) {
103
- if (signal.aborted) throw signal.reason;
104
- if (err instanceof MediaFetchError) throw err;
105
- throw new RetryableLineMediaFetchError(`LINE media download failed for message ${messageId}`, { cause: err });
106
- }
107
- throw new MediaFetchError("http_error", `LINE media for message ${messageId} was still preparing (HTTP 202) after ${CONTENT_READY_MAX_ATTEMPTS} attempts`, { status: 202 });
108
- }
109
- function isRetryableLineInboundMediaError(err) {
110
- if (err instanceof RetryableLineMediaFetchError) return true;
111
- if (!(err instanceof MediaFetchError)) return false;
112
- if (err.code === "http_error") return err.status === 202 || err.status === 408 || err.status === 429 || typeof err.status === "number" && err.status >= 500;
113
- return false;
114
- }
115
- async function downloadLineMedia(messageId, channelAccessToken, maxBytes = 10485760, options) {
116
- options?.signal?.throwIfAborted();
117
- const deadlineAbort = new AbortController();
118
- const signal = options?.signal ? AbortSignal.any([options.signal, deadlineAbort.signal]) : deadlineAbort.signal;
119
- const deadline = setTimeout(() => {
120
- deadlineAbort.abort(new RetryableLineMediaFetchError(`LINE media for message ${messageId} did not download within ${CONTENT_DOWNLOAD_TIMEOUT_MS / 1e3} seconds`));
121
- }, CONTENT_DOWNLOAD_TIMEOUT_MS);
122
- deadline.unref();
123
- try {
124
- const response = await fetchLineContentWhenReady(messageId, channelAccessToken, signal);
125
- let saved;
126
- try {
127
- saved = await saveMediaStream(lineResponseBodyChunks(response, messageId, signal, () => clearTimeout(deadline)), response.headers.get("content-type") ?? void 0, "inbound", maxBytes, options?.originalFilename);
128
- } catch (err) {
129
- await response.body?.cancel(signal.aborted ? signal.reason : err).catch(() => void 0);
130
- if (signal.aborted) throw signal.reason;
131
- throw err;
132
- }
133
- options?.signal?.throwIfAborted();
134
- logVerbose(`line: persisted media ${messageId} to ${saved.path} (${saved.size} bytes)`);
135
- return {
136
- path: saved.path,
137
- contentType: saved.contentType,
138
- size: saved.size
139
- };
140
- } finally {
141
- clearTimeout(deadline);
142
- }
143
- }
144
- //#endregion
145
45
  //#region extensions/line/src/auto-reply-delivery.ts
146
46
  function toLineDeliveryError(error) {
147
47
  return error instanceof Error ? error : new Error("LINE message send failed", { cause: error });
@@ -409,46 +309,73 @@ function buildPeerId(source) {
409
309
  if (source.type === "user" && source.userId) return source.userId;
410
310
  return "unknown";
411
311
  }
412
- async function resolveLineInboundRoute(params) {
413
- recordChannelActivity({
414
- channel: "line",
415
- accountId: params.account.accountId,
416
- direction: "inbound"
417
- });
312
+ async function prepareLineInboundRoute(params) {
418
313
  const { userId, groupId, roomId, isGroup } = getLineSourceInfo(params.source);
419
314
  const peerId = buildPeerId(params.source);
420
- let route = resolveAgentRoute({
421
- cfg: params.cfg,
315
+ const routeInput = {
422
316
  channel: "line",
423
317
  accountId: params.account.accountId,
424
318
  peer: {
425
319
  kind: isGroup ? "group" : "direct",
426
320
  id: peerId
427
321
  }
322
+ };
323
+ const conversation = {
324
+ channel: "line",
325
+ accountId: params.account.accountId,
326
+ conversationId: peerId
327
+ };
328
+ const inspection = await getSessionBindingService().inspectByConversationAsync(conversation);
329
+ if (inspection.status === "unavailable") throw new Error("LINE conversation binding owner is temporarily unavailable; retry the message.");
330
+ const resolveScopeRoute = (agentId) => resolveAgentRoute({
331
+ ...routeInput,
332
+ cfg: { session: params.cfg.session },
333
+ defaultAgentId: agentId
334
+ });
335
+ const selection = inspectRuntimeConversationBindingRoute({
336
+ route: resolveScopeRoute(),
337
+ inspection
338
+ });
339
+ const metadataAgentId = selection.bindingRecord?.metadata?.agentId;
340
+ const hasBoundAgent = selection.boundSessionKey && (parseAgentSessionKey(selection.boundSessionKey) || typeof metadataAgentId === "string" && metadataAgentId.trim());
341
+ const baseRoute = hasBoundAgent ? resolveScopeRoute(selection.boundAgentId) : resolveAgentRoute({
342
+ ...routeInput,
343
+ cfg: params.cfg
428
344
  });
429
- const configuredRoute = resolveConfiguredBindingRoute({
345
+ const configuredRoute = hasBoundAgent ? {
346
+ route: baseRoute,
347
+ bindingResolution: null
348
+ } : resolveConfiguredBindingRoute({
430
349
  cfg: params.cfg,
431
- route,
432
- conversation: {
433
- channel: "line",
434
- accountId: params.account.accountId,
435
- conversationId: peerId
436
- }
350
+ route: baseRoute,
351
+ conversation
437
352
  });
438
- let configuredBinding = configuredRoute.bindingResolution;
439
- const configuredBindingSessionKey = configuredRoute.boundSessionKey ?? "";
440
- route = configuredRoute.route;
441
- const runtimeRoute = resolveRuntimeConversationBindingRoute({
442
- route,
443
- conversation: {
444
- channel: "line",
445
- accountId: params.account.accountId,
446
- conversationId: peerId
447
- }
353
+ const runtimeRoute = inspectRuntimeConversationBindingRoute({
354
+ route: configuredRoute.route,
355
+ inspection
356
+ });
357
+ return {
358
+ userId,
359
+ groupId,
360
+ roomId,
361
+ isGroup,
362
+ peerId,
363
+ route: runtimeRoute.route,
364
+ mentionAgentId: baseRoute.agentId,
365
+ runtimeRoute,
366
+ configuredBinding: runtimeRoute.bindingRecord ? null : configuredRoute.bindingResolution,
367
+ configuredBindingSessionKey: configuredRoute.boundSessionKey ?? ""
368
+ };
369
+ }
370
+ async function resolveLineInboundRoute(params) {
371
+ recordChannelActivity({
372
+ channel: "line",
373
+ accountId: params.account.accountId,
374
+ direction: "inbound"
448
375
  });
449
- route = runtimeRoute.route;
376
+ const { userId, groupId, roomId, isGroup, peerId, route, runtimeRoute, configuredBinding, configuredBindingSessionKey } = params.preparedRoute ?? await prepareLineInboundRoute(params);
450
377
  if (runtimeRoute.bindingRecord) {
451
- configuredBinding = null;
378
+ await getSessionBindingService().touchAsync(runtimeRoute.bindingRecord.bindingId, void 0, runtimeRoute.bindingRecord.conversation);
452
379
  logVerbose(runtimeRoute.boundSessionKey ? `line: routed via bound conversation ${peerId} -> ${runtimeRoute.boundSessionKey}` : `line: plugin-bound conversation ${peerId}`);
453
380
  }
454
381
  if (configuredBinding) {
@@ -538,7 +465,7 @@ async function finalizeLineInboundContext(params) {
538
465
  const body = formatInboundEnvelope({
539
466
  channel: "LINE",
540
467
  from: conversationLabel,
541
- timestamp: params.timestamp,
468
+ timestamp: params.event.timestamp,
542
469
  body: agentBody,
543
470
  chatType: params.source.isGroup ? "group" : "direct",
544
471
  sender: {
@@ -553,7 +480,7 @@ async function finalizeLineInboundContext(params) {
553
480
  channel: "line",
554
481
  accountId: params.route.accountId,
555
482
  messageId: params.messageSid,
556
- timestamp: params.timestamp,
483
+ timestamp: params.event.timestamp,
557
484
  from: address,
558
485
  sender: {
559
486
  id: senderId,
@@ -565,9 +492,7 @@ async function finalizeLineInboundContext(params) {
565
492
  label: conversationLabel
566
493
  },
567
494
  route: {
568
- agentId: params.route.agentId,
569
- dmScope: params.route.dmScope,
570
- accountId: params.route.accountId,
495
+ ...params.route,
571
496
  routeSessionKey: params.route.sessionKey
572
497
  },
573
498
  reply: {
@@ -595,7 +520,7 @@ async function finalizeLineInboundContext(params) {
595
520
  const pinnedMainDmOwner = !params.source.isGroup ? resolvePinnedMainDmOwnerFromAllowlist({
596
521
  dmScope: params.cfg.session?.dmScope,
597
522
  allowFrom: params.account.config.allowFrom,
598
- normalizeEntry: (entry) => normalizeAllowFrom([entry]).entries[0]
523
+ normalizeEntry: (entry) => normalizeLineAllowEntry(entry) || void 0
599
524
  }) : null;
600
525
  const inboundLastRouteSessionKey = resolveInboundLastRouteSessionKey({
601
526
  route: params.route,
@@ -609,7 +534,14 @@ async function finalizeLineInboundContext(params) {
609
534
  }
610
535
  return {
611
536
  ctxPayload,
537
+ event: params.event,
538
+ userId: params.source.userId,
539
+ groupId: params.source.groupId,
540
+ roomId: params.source.roomId,
541
+ isGroup: params.source.isGroup,
542
+ route: params.route,
612
543
  replyToken: params.event.replyToken,
544
+ accountId: params.account.accountId,
613
545
  skillFilter: groupConfig?.skills,
614
546
  turn: {
615
547
  storePath,
@@ -640,11 +572,11 @@ async function buildLineMessageContext(params) {
640
572
  const { userId, groupId, roomId, isGroup, peerId, route } = await resolveLineInboundRoute({
641
573
  source,
642
574
  cfg,
643
- account
575
+ account,
576
+ preparedRoute: params.preparedRoute
644
577
  });
645
578
  const message = event.message;
646
579
  const messageId = message.id;
647
- const timestamp = event.timestamp;
648
580
  const textContent = extractMessageText(message);
649
581
  const nativeMediaKind = extractNativeMediaKind(message);
650
582
  const mediaFacts = allMedia.length > 0 ? allMedia.map((media) => ({
@@ -678,7 +610,7 @@ async function buildLineMessageContext(params) {
678
610
  address: loc.address
679
611
  });
680
612
  }
681
- const finalized = await finalizeLineInboundContext({
613
+ return finalizeLineInboundContext({
682
614
  cfg,
683
615
  account,
684
616
  event,
@@ -694,7 +626,6 @@ async function buildLineMessageContext(params) {
694
626
  agentBody,
695
627
  commandBody: resolveLineMentionStrippedText(message) || rawBody,
696
628
  mentions: params.mentions,
697
- timestamp,
698
629
  messageSid: messageId,
699
630
  commandAuthorized,
700
631
  channelIngress: await params.resolveChannelIngress?.({
@@ -712,19 +643,6 @@ async function buildLineMessageContext(params) {
712
643
  },
713
644
  inboundHistory
714
645
  });
715
- return {
716
- ctxPayload: finalized.ctxPayload,
717
- turn: finalized.turn,
718
- skillFilter: finalized.skillFilter,
719
- event,
720
- userId,
721
- groupId,
722
- roomId,
723
- isGroup,
724
- route,
725
- replyToken: event.replyToken,
726
- accountId: account.accountId
727
- };
728
646
  }
729
647
  async function buildLinePostbackContext(params) {
730
648
  const { event, cfg, account, commandAuthorized } = params;
@@ -749,7 +667,7 @@ async function buildLinePostbackContext(params) {
749
667
  if (picked) agentBody += ` ${key}=${picked}`;
750
668
  }
751
669
  const messageSid = event.replyToken ? `postback:${event.replyToken}` : `postback:${timestamp}`;
752
- const finalized = await finalizeLineInboundContext({
670
+ return finalizeLineInboundContext({
753
671
  cfg,
754
672
  account,
755
673
  event,
@@ -763,7 +681,6 @@ async function buildLinePostbackContext(params) {
763
681
  },
764
682
  rawBody,
765
683
  agentBody,
766
- timestamp,
767
684
  messageSid,
768
685
  commandAuthorized,
769
686
  channelIngress: await params.resolveChannelIngress?.({
@@ -776,19 +693,111 @@ async function buildLinePostbackContext(params) {
776
693
  media: [],
777
694
  verboseLog: { kind: "postback" }
778
695
  });
779
- return {
780
- ctxPayload: finalized.ctxPayload,
781
- turn: finalized.turn,
782
- skillFilter: finalized.skillFilter,
783
- event,
784
- userId,
785
- groupId,
786
- roomId,
787
- isGroup,
788
- route,
789
- replyToken: event.replyToken,
790
- accountId: account.accountId
791
- };
696
+ }
697
+ //#endregion
698
+ //#region extensions/line/src/download.ts
699
+ const CONTENT_READY_MAX_ATTEMPTS = 6;
700
+ const CONTENT_READY_BASE_DELAY_MS = 500;
701
+ const CONTENT_READY_MAX_DELAY_MS = 4e3;
702
+ const CONTENT_DOWNLOAD_TIMEOUT_MS = 15e3;
703
+ const LINE_CONTENT_BASE_URL = "https://api-data.line.me/v2/bot/message";
704
+ var RetryableLineMediaFetchError = class extends MediaFetchError {
705
+ constructor(message, options) {
706
+ super("fetch_failed", message, options);
707
+ this.name = "RetryableLineMediaFetchError";
708
+ }
709
+ };
710
+ function contentBackoffDelayMs(attempt) {
711
+ return Math.min(CONTENT_READY_BASE_DELAY_MS * 2 ** attempt, CONTENT_READY_MAX_DELAY_MS);
712
+ }
713
+ function lineContentUrl(messageId) {
714
+ return `${LINE_CONTENT_BASE_URL}/${encodeURIComponent(messageId)}/content`;
715
+ }
716
+ async function* lineResponseBodyChunks(response, messageId, signal, onComplete) {
717
+ const body = response.body;
718
+ if (!body) throw new RetryableLineMediaFetchError(`LINE media response for message ${messageId} had no body`);
719
+ const reader = body.getReader();
720
+ let completed = false;
721
+ try {
722
+ while (true) {
723
+ let chunk;
724
+ try {
725
+ chunk = await reader.read();
726
+ } catch (err) {
727
+ if (signal.aborted) throw signal.reason;
728
+ throw new RetryableLineMediaFetchError(`LINE media response stream failed for message ${messageId}`, { cause: err });
729
+ }
730
+ if (chunk.done) {
731
+ completed = true;
732
+ onComplete();
733
+ return;
734
+ }
735
+ if (chunk.value.byteLength > 0) yield chunk.value;
736
+ }
737
+ } finally {
738
+ if (!completed) await reader.cancel(signal.aborted ? signal.reason : void 0).catch(() => void 0);
739
+ try {
740
+ reader.releaseLock();
741
+ } catch {}
742
+ }
743
+ }
744
+ async function fetchLineContentWhenReady(messageId, channelAccessToken, signal) {
745
+ try {
746
+ for (let attempt = 0; attempt < CONTENT_READY_MAX_ATTEMPTS; attempt++) {
747
+ const response = await fetchWithRuntimeDispatcherOrMockedGlobal(lineContentUrl(messageId), {
748
+ headers: { Authorization: `Bearer ${channelAccessToken}` },
749
+ redirect: "error",
750
+ signal
751
+ });
752
+ if (response.status === 200) {
753
+ if (!response.body) throw new RetryableLineMediaFetchError(`LINE media response for message ${messageId} had no body`);
754
+ return response;
755
+ }
756
+ await response.body?.cancel().catch(() => void 0);
757
+ if (response.status !== 202) throw new MediaFetchError("http_error", `LINE media download failed for message ${messageId} (HTTP ${response.status})`, { status: response.status });
758
+ if (attempt < 5) await setTimeout$1(contentBackoffDelayMs(attempt), void 0, { signal });
759
+ }
760
+ } catch (err) {
761
+ if (signal.aborted) throw signal.reason;
762
+ if (err instanceof MediaFetchError) throw err;
763
+ throw new RetryableLineMediaFetchError(`LINE media download failed for message ${messageId}`, { cause: err });
764
+ }
765
+ throw new MediaFetchError("http_error", `LINE media for message ${messageId} was still preparing (HTTP 202) after ${CONTENT_READY_MAX_ATTEMPTS} attempts`, { status: 202 });
766
+ }
767
+ function isRetryableLineInboundMediaError(err) {
768
+ if (err instanceof RetryableLineMediaFetchError) return true;
769
+ if (!(err instanceof MediaFetchError)) return false;
770
+ if (err.code === "http_error") return err.status === 202 || err.status === 408 || err.status === 429 || typeof err.status === "number" && err.status >= 500;
771
+ return false;
772
+ }
773
+ async function downloadLineMedia(messageId, channelAccessToken, maxBytes = 10485760, options) {
774
+ options?.signal?.throwIfAborted();
775
+ const deadlineAbort = new AbortController();
776
+ const signal = options?.signal ? AbortSignal.any([options.signal, deadlineAbort.signal]) : deadlineAbort.signal;
777
+ const deadline = setTimeout(() => {
778
+ deadlineAbort.abort(new RetryableLineMediaFetchError(`LINE media for message ${messageId} did not download within ${CONTENT_DOWNLOAD_TIMEOUT_MS / 1e3} seconds`));
779
+ }, CONTENT_DOWNLOAD_TIMEOUT_MS);
780
+ deadline.unref();
781
+ try {
782
+ const response = await fetchLineContentWhenReady(messageId, channelAccessToken, signal);
783
+ let saved;
784
+ try {
785
+ saved = await saveMediaStream(lineResponseBodyChunks(response, messageId, signal, () => clearTimeout(deadline)), response.headers.get("content-type") ?? void 0, "inbound", maxBytes, options?.originalFilename);
786
+ } catch (err) {
787
+ await response.body?.cancel(signal.aborted ? signal.reason : err).catch(() => void 0);
788
+ if (signal.aborted) throw signal.reason;
789
+ throw err;
790
+ }
791
+ options?.signal?.throwIfAborted();
792
+ logVerbose(`line: persisted media ${messageId} to ${saved.path} (${saved.size} bytes)`);
793
+ return {
794
+ path: saved.path,
795
+ contentType: saved.contentType,
796
+ size: saved.size
797
+ };
798
+ } finally {
799
+ clearTimeout(deadline);
800
+ }
792
801
  }
793
802
  //#endregion
794
803
  //#region extensions/line/src/group-history.ts
@@ -916,6 +925,10 @@ async function resolveLineEventAdmission(event, context) {
916
925
  groupId,
917
926
  roomId
918
927
  });
928
+ if (isGroup && groupConfig?.enabled === false) {
929
+ logVerbose(`Blocked line group ${groupId ?? roomId ?? "unknown"} (group disabled)`);
930
+ return null;
931
+ }
919
932
  const rawText = resolveEventRawText(event);
920
933
  const requireMention = isGroup ? groupConfig?.requireMention !== false : false;
921
934
  const dmPolicy = account.config.dmPolicy ?? "pairing";
@@ -926,30 +939,9 @@ async function resolveLineEventAdmission(event, context) {
926
939
  });
927
940
  const groupPolicy = runtimeGroupPolicy === "disabled" ? "disabled" : groupConfig?.allowFrom !== void 0 ? "allowlist" : runtimeGroupPolicy;
928
941
  const groupAllowFrom = normalizeStringEntries(firstDefined(groupConfig?.allowFrom, account.config.groupAllowFrom));
929
- const mentionFacts = (() => {
930
- if (!isGroup || event.type !== "message") return;
931
- const peerId = groupId ?? roomId ?? userId ?? "unknown";
932
- const { agentId } = resolveAgentRoute({
933
- cfg,
934
- channel: "line",
935
- accountId: account.accountId,
936
- peer: {
937
- kind: "group",
938
- id: peerId
939
- }
940
- });
941
- const mentionRegexes = buildMentionRegexes(cfg, agentId);
942
- const wasMentionedByNative = isLineBotMentioned(event.message);
943
- const wasMentionedByPattern = event.message.type === "text" ? matchesMentionPatterns(rawText, mentionRegexes) : false;
944
- return {
945
- canDetectMention: event.message.type === "text",
946
- wasMentioned: wasMentionedByNative || wasMentionedByPattern,
947
- explicitlyMentionedBot: wasMentionedByNative,
948
- hasAnyMention: hasAnyLineMention(event.message),
949
- implicitMentionKinds: implicitMentionKindWhen("quoted_bot", quotesLineBotMessage(account.accountId, resolveLineQuotedMessageId(event.message)))
950
- };
951
- })();
952
- const resolveAccess = async (contextBinding) => await resolveStableChannelMessageIngress({
942
+ let preparedRoute;
943
+ let mentionFacts;
944
+ const resolveAccess = async (contextBinding) => await getLineRuntime().channel.inbound.ingress.resolveStable({
953
945
  channelId: "line",
954
946
  accountId: account.accountId,
955
947
  identity: {
@@ -966,10 +958,6 @@ async function resolveLineEventAdmission(event, context) {
966
958
  id: (groupId ?? roomId ?? senderId) || "unknown"
967
959
  },
968
960
  ...contextBinding ? { contextBinding } : {},
969
- ...isGroup && groupConfig?.enabled === false ? { route: {
970
- id: "line:group-config",
971
- enabled: false
972
- } } : {},
973
961
  mentionFacts,
974
962
  event: { kind: event.type === "join" ? "system" : event.type },
975
963
  dmPolicy,
@@ -993,35 +981,53 @@ async function resolveLineEventAdmission(event, context) {
993
981
  groupOwnerAllowFrom: "none"
994
982
  }
995
983
  });
996
- const access = await resolveAccess();
984
+ let access = await resolveAccess();
985
+ if (isGroup && event.type === "message" && isLineEventAdmitted(access)) {
986
+ preparedRoute = await prepareLineInboundRoute({
987
+ source: event.source,
988
+ cfg,
989
+ account
990
+ });
991
+ const mentionRegexes = buildMentionRegexes(cfg, preparedRoute.mentionAgentId);
992
+ const wasMentionedByNative = isLineBotMentioned(event.message);
993
+ const wasMentionedByPattern = event.message.type === "text" ? matchesMentionPatterns(rawText, mentionRegexes) : false;
994
+ mentionFacts = {
995
+ canDetectMention: event.message.type === "text",
996
+ wasMentioned: wasMentionedByNative || wasMentionedByPattern,
997
+ explicitlyMentionedBot: wasMentionedByNative,
998
+ hasAnyMention: hasAnyLineMention(event.message),
999
+ implicitMentionKinds: implicitMentionKindWhen("quoted_bot", quotesLineBotMessage(account.accountId, resolveLineQuotedMessageId(event.message)))
1000
+ };
1001
+ access = await resolveAccess();
1002
+ }
997
1003
  warnMissingProviderGroupPolicyFallbackOnce({
998
1004
  providerMissingFallbackApplied,
999
1005
  providerKey: "line",
1000
1006
  accountId: account.accountId,
1001
1007
  log: (message) => logVerbose(message)
1002
1008
  });
1003
- if (event.type === "join") return groupConfig?.enabled !== false && groupPolicy !== "disabled" && (groupPolicy !== "allowlist" || access.state.allowlists.group.hasMatchableEntries) ? {
1009
+ if (event.type === "join") return groupPolicy !== "disabled" && (groupPolicy !== "allowlist" || access.state.allowlists.group.hasMatchableEntries) ? {
1004
1010
  access,
1005
1011
  resolveBoundAccess: resolveAccess
1006
1012
  } : null;
1007
- if (isLineEventAdmitted(access)) return {
1008
- access,
1009
- resolveBoundAccess: resolveAccess,
1010
- mentions: mentionFacts ? {
1013
+ if (isLineEventAdmitted(access)) {
1014
+ const mentions = mentionFacts ? {
1011
1015
  ...mentionFacts,
1012
1016
  wasMentioned: access.activationAccess.effectiveWasMentioned ?? mentionFacts.wasMentioned,
1013
1017
  requireMention
1014
- } : void 0
1015
- };
1018
+ } : void 0;
1019
+ return {
1020
+ access,
1021
+ resolveBoundAccess: resolveAccess,
1022
+ mentions,
1023
+ preparedRoute
1024
+ };
1025
+ }
1016
1026
  if (access.senderAccess.decision === "allow") {
1017
1027
  logVerbose(`Blocked line event (${access.ingress.reasonCode})`);
1018
1028
  return null;
1019
1029
  }
1020
1030
  if (isGroup) {
1021
- if (groupConfig?.enabled === false) {
1022
- logVerbose(`Blocked line group ${groupId ?? roomId ?? "unknown"} (group disabled)`);
1023
- return null;
1024
- }
1025
1031
  if (groupConfig?.allowFrom !== void 0) {
1026
1032
  if (!senderId) {
1027
1033
  logVerbose("Blocked line group message (group allowFrom override, no sender ID)");
@@ -1150,6 +1156,7 @@ async function handleMessageEvent(event, context, setParts) {
1150
1156
  ...context.missingParts === void 0 ? {} : { missingParts: context.missingParts },
1151
1157
  cfg,
1152
1158
  account,
1159
+ preparedRoute: decision.preparedRoute,
1153
1160
  commandAuthorized: decision.access.commandAccess.authorized,
1154
1161
  resolveChannelIngress: decision.resolveBoundAccess,
1155
1162
  inboundHistory: historyReservation.inboundHistory,
@@ -1168,14 +1175,6 @@ async function handleMessageEvent(event, context, setParts) {
1168
1175
  historyReservation.release();
1169
1176
  }
1170
1177
  }
1171
- async function handleFollowEvent(event, _context) {
1172
- const { userId } = getLineSourceInfo(event.source);
1173
- logVerbose(`line: user ${userId ?? "unknown"} followed`);
1174
- }
1175
- async function handleUnfollowEvent(event, _context) {
1176
- const { userId } = getLineSourceInfo(event.source);
1177
- logVerbose(`line: user ${userId ?? "unknown"} unfollowed`);
1178
- }
1179
1178
  async function handleJoinEvent(event, context) {
1180
1179
  const { groupId, roomId, isGroup } = getLineSourceInfo(event.source);
1181
1180
  const conversationId = groupId ?? roomId;
@@ -1213,10 +1212,6 @@ async function handleJoinEvent(event, context) {
1213
1212
  }
1214
1213
  });
1215
1214
  }
1216
- async function handleLeaveEvent(event, _context) {
1217
- const { groupId, roomId } = getLineSourceInfo(event.source);
1218
- logVerbose(`line: bot left ${groupId ? `group ${groupId}` : `room ${roomId}`}`);
1219
- }
1220
1215
  /** What a tap that did not answer the question has to tell the person who tapped. */
1221
1216
  function lineQuestionOutcomeNotice(status) {
1222
1217
  if (status === "already-terminal") return "That question is no longer waiting for an answer.";
@@ -1291,17 +1286,19 @@ async function handleLineWebhookEvent(event, context, setParts = []) {
1291
1286
  await handleMessageEvent(event, context, setParts.filter((part) => part.type === "message"));
1292
1287
  break;
1293
1288
  case "follow":
1294
- await handleFollowEvent(event, context);
1295
- break;
1296
- case "unfollow":
1297
- await handleUnfollowEvent(event, context);
1289
+ case "unfollow": {
1290
+ const { userId } = getLineSourceInfo(event.source);
1291
+ logVerbose(`line: user ${userId ?? "unknown"} ${event.type}ed`);
1298
1292
  break;
1293
+ }
1299
1294
  case "join":
1300
1295
  await handleJoinEvent(event, context);
1301
1296
  break;
1302
- case "leave":
1303
- await handleLeaveEvent(event, context);
1297
+ case "leave": {
1298
+ const { groupId, roomId } = getLineSourceInfo(event.source);
1299
+ logVerbose(`line: bot left ${groupId ? `group ${groupId}` : `room ${roomId}`}`);
1304
1300
  break;
1301
+ }
1305
1302
  case "postback":
1306
1303
  await handlePostbackEvent(event, context);
1307
1304
  break;
@@ -1311,40 +1308,17 @@ async function handleLineWebhookEvent(event, context, setParts = []) {
1311
1308
  //#endregion
1312
1309
  //#region extensions/line/src/inbound-image-set.ts
1313
1310
  const IMAGE_SET_FLUSH_DELAY_MS = 4e3;
1314
- /**
1315
- * Ordered by the index the sender picked, falling back to arrival.
1316
- *
1317
- * `index` is optional per part in LINE's contract, so a set can arrive partly
1318
- * indexed. Choosing the key per pair would make the comparator intransitive and
1319
- * the resulting order depend on insertion; ranking unindexed parts last keeps
1320
- * one total order for every mix.
1321
- */
1322
1311
  function orderedParts(pending) {
1323
1312
  return [...pending.parts.values()].toSorted((left, right) => (left.index ?? Number.MAX_SAFE_INTEGER) - (right.index ?? Number.MAX_SAFE_INTEGER) || left.arrivedAt - right.arrivedAt);
1324
1313
  }
1325
- /**
1326
- * Buffers the parts of a LINE image set until the set is whole.
1327
- *
1328
- * The first part becomes the set's holder: its call does not resolve until the
1329
- * set completes or its wait expires, and it is the one that delivers. Keeping
1330
- * that call open is what keeps the combined turn inside a live ingress
1331
- * adoption - a turn dispatched after every part had returned is refused by
1332
- * admission, so a set that never completes would never be delivered at all.
1333
- */
1334
1314
  function createLineImageSetIngressBuffer() {
1335
1315
  const pendingBySet = /* @__PURE__ */ new Map();
1336
1316
  const deliveredBySet = /* @__PURE__ */ new Map();
1337
1317
  const pendingKey = (laneKey, senderKey, setId) => `${laneKey}\u0000${senderKey}\u0000${setId}`;
1338
1318
  const laneChain = /* @__PURE__ */ new Map();
1339
1319
  const enterLane = async (laneKey) => {
1340
- let release = () => {};
1341
- const held = new Promise((resolve) => {
1342
- release = resolve;
1343
- });
1344
- let entered = () => {};
1345
- const turn = new Promise((resolve) => {
1346
- entered = resolve;
1347
- });
1320
+ const { promise: held, resolve: release } = createDeferred();
1321
+ const { promise: turn, resolve: entered } = createDeferred();
1348
1322
  enqueueKeyedTask({
1349
1323
  tails: laneChain,
1350
1324
  key: laneKey,
@@ -1379,10 +1353,7 @@ function createLineImageSetIngressBuffer() {
1379
1353
  }
1380
1354
  return null;
1381
1355
  }
1382
- let release = () => {};
1383
- const whole = new Promise((resolve) => {
1384
- release = resolve;
1385
- });
1356
+ const { promise: whole, resolve: release } = createDeferred();
1386
1357
  const pending = {
1387
1358
  parts: /* @__PURE__ */ new Map([[input.messageId, part]]),
1388
1359
  total: input.total,
@@ -1718,7 +1689,7 @@ function createLineBot(opts) {
1718
1689
  ...control.turnAdoptionLifecycle ? { turnAdoptionLifecycle: control.turnAdoptionLifecycle } : {},
1719
1690
  ...control.missingParts === void 0 ? {} : { missingParts: control.missingParts },
1720
1691
  groupHistories,
1721
- historyLimit: account.config.historyLimit ?? cfg.messages?.groupChat?.historyLimit ?? DEFAULT_GROUP_HISTORY_LIMIT
1692
+ historyLimit: resolvePromptHistoryLimit(account.config.historyLimit ?? cfg.messages?.groupChat?.historyLimit)
1722
1693
  });
1723
1694
  }
1724
1695
  });
@@ -1773,9 +1744,9 @@ function parseLineWebhookBody(rawBody) {
1773
1744
  //#endregion
1774
1745
  //#region extensions/line/src/webhook-node.ts
1775
1746
  const LINE_WEBHOOK_MAX_BODY_BYTES = 1048576;
1776
- const LINE_WEBHOOK_PREAUTH_MAX_BODY_BYTES$1 = 65536;
1777
- const LINE_WEBHOOK_PREAUTH_BODY_TIMEOUT_MS$1 = 5e3;
1778
- async function readLineWebhookRequestBody(req, maxBytes = LINE_WEBHOOK_MAX_BODY_BYTES, timeoutMs = LINE_WEBHOOK_PREAUTH_BODY_TIMEOUT_MS$1) {
1747
+ const LINE_WEBHOOK_PREAUTH_MAX_BODY_BYTES = 65536;
1748
+ const LINE_WEBHOOK_PREAUTH_BODY_TIMEOUT_MS = 5e3;
1749
+ async function readLineWebhookRequestBody(req, maxBytes = LINE_WEBHOOK_MAX_BODY_BYTES, timeoutMs = LINE_WEBHOOK_PREAUTH_BODY_TIMEOUT_MS) {
1779
1750
  return await readRequestBodyWithLimit(req, {
1780
1751
  maxBytes,
1781
1752
  timeoutMs,
@@ -1798,6 +1769,12 @@ function createLineNodeWebhookHandler(params) {
1798
1769
  const maxBodyBytes = params.maxBodyBytes ?? LINE_WEBHOOK_MAX_BODY_BYTES;
1799
1770
  const readBody = params.readBody ?? readLineWebhookRequestBody;
1800
1771
  return async (req, res) => {
1772
+ const targets = params.getTargets();
1773
+ if (req.method !== "POST" && targets.length === 0) {
1774
+ res.statusCode = 404;
1775
+ res.end("Not Found");
1776
+ return;
1777
+ }
1801
1778
  if (req.method === "GET" || req.method === "HEAD") {
1802
1779
  if (req.method === "HEAD") {
1803
1780
  res.statusCode = 204;
@@ -1826,14 +1803,22 @@ function createLineNodeWebhookHandler(params) {
1826
1803
  res.end(JSON.stringify({ error: "Missing X-Line-Signature header" }));
1827
1804
  return;
1828
1805
  }
1829
- const rawBody = await readBody(req, Math.min(maxBodyBytes, LINE_WEBHOOK_PREAUTH_MAX_BODY_BYTES$1), LINE_WEBHOOK_PREAUTH_BODY_TIMEOUT_MS$1);
1830
- if (!validateLineSignature(rawBody, signature, params.channelSecret)) {
1806
+ const rawBody = await readBody(req, Math.min(maxBodyBytes, LINE_WEBHOOK_PREAUTH_MAX_BODY_BYTES), LINE_WEBHOOK_PREAUTH_BODY_TIMEOUT_MS);
1807
+ const match = resolveSingleWebhookTarget(targets, (target) => validateLineSignature(rawBody, signature, target.channelSecret));
1808
+ if (match.kind === "none") {
1831
1809
  logVerbose("line: webhook signature validation failed");
1832
1810
  res.statusCode = 401;
1833
1811
  res.setHeader("Content-Type", "application/json");
1834
1812
  res.end(JSON.stringify({ error: "Invalid signature" }));
1835
1813
  return;
1836
1814
  }
1815
+ if (match.kind === "ambiguous") {
1816
+ logVerbose("line: webhook signature matched multiple accounts");
1817
+ res.statusCode = 401;
1818
+ res.setHeader("Content-Type", "application/json");
1819
+ res.end(JSON.stringify({ error: "Ambiguous webhook target" }));
1820
+ return;
1821
+ }
1837
1822
  const body = parseLineWebhookBody(rawBody);
1838
1823
  if (!body) {
1839
1824
  res.statusCode = 400;
@@ -1841,10 +1826,9 @@ function createLineNodeWebhookHandler(params) {
1841
1826
  res.end(JSON.stringify({ error: "Invalid webhook payload" }));
1842
1827
  return;
1843
1828
  }
1844
- params.onRequestAuthenticated?.();
1845
1829
  if (body.events && body.events.length > 0) {
1846
1830
  logVerbose(`line: received ${body.events.length} webhook events`);
1847
- await params.bot.handleWebhook(body);
1831
+ if (await match.target.bot.handleWebhook(body) === "durable") res.setHeader("x-openclaw-delivery-accepted", "durable");
1848
1832
  }
1849
1833
  res.statusCode = 200;
1850
1834
  res.setHeader("Content-Type", "application/json");
@@ -1863,8 +1847,6 @@ function createLineNodeWebhookHandler(params) {
1863
1847
  //#endregion
1864
1848
  //#region extensions/line/src/monitor.ts
1865
1849
  const lineWebhookInFlightLimiter = createWebhookInFlightLimiter();
1866
- const LINE_WEBHOOK_PREAUTH_MAX_BODY_BYTES = 65536;
1867
- const LINE_WEBHOOK_PREAUTH_BODY_TIMEOUT_MS = 5e3;
1868
1850
  async function registerLineWebhookTarget(params, bot) {
1869
1851
  try {
1870
1852
  return registerWebhookTargetWithPluginRoute(params);
@@ -2017,10 +1999,9 @@ async function monitorLineProvider(opts) {
2017
1999
  });
2018
2000
  const normalizedPath = resolveLineWebhookPath(webhookPath);
2019
2001
  const webhookRouteKey = canonicalizeWebhookRouteKey(normalizedPath);
2020
- const createScopedLineWebhookHandler = (target) => createLineNodeWebhookHandler({
2021
- channelSecret: target.channelSecret,
2022
- bot: target.bot,
2023
- runtime: target.runtime
2002
+ const handleWebhook = createLineNodeWebhookHandler({
2003
+ getTargets: () => lineWebhookTargets.get(webhookRouteKey) ?? [],
2004
+ runtime
2024
2005
  });
2025
2006
  const { unregister: unregisterHttp } = await registerLineWebhookTarget({
2026
2007
  targetsByPath: lineWebhookTargets,
@@ -2039,15 +2020,8 @@ async function monitorLineProvider(opts) {
2039
2020
  log: (msg) => logVerbose(msg),
2040
2021
  throwOnFailure: true,
2041
2022
  handler: async (req, res) => {
2042
- const targets = lineWebhookTargets.get(webhookRouteKey) ?? [];
2043
- const firstTarget = targets[0];
2044
2023
  if (req.method !== "POST") {
2045
- if (!firstTarget) {
2046
- res.statusCode = 404;
2047
- res.end("Not Found");
2048
- return;
2049
- }
2050
- await createScopedLineWebhookHandler(firstTarget)(req, res);
2024
+ await handleWebhook(req, res);
2051
2025
  return;
2052
2026
  }
2053
2027
  const requestLifecycle = beginWebhookRequestPipelineOrReject({
@@ -2058,53 +2032,7 @@ async function monitorLineProvider(opts) {
2058
2032
  });
2059
2033
  if (!requestLifecycle.ok) return;
2060
2034
  try {
2061
- const signatureHeader = req.headers["x-line-signature"];
2062
- const signature = typeof signatureHeader === "string" ? signatureHeader.trim() : Array.isArray(signatureHeader) ? (signatureHeader[0] ?? "").trim() : "";
2063
- if (!signature) {
2064
- logVerbose("line: webhook missing X-Line-Signature header");
2065
- res.statusCode = 400;
2066
- res.setHeader("Content-Type", "application/json");
2067
- res.end(JSON.stringify({ error: "Missing X-Line-Signature header" }));
2068
- return;
2069
- }
2070
- const rawBody = await readLineWebhookRequestBody(req, LINE_WEBHOOK_PREAUTH_MAX_BODY_BYTES, LINE_WEBHOOK_PREAUTH_BODY_TIMEOUT_MS);
2071
- const match = resolveSingleWebhookTarget(targets, (target) => validateLineSignature(rawBody, signature, target.channelSecret));
2072
- if (match.kind === "none") {
2073
- logVerbose("line: webhook signature validation failed");
2074
- res.statusCode = 401;
2075
- res.setHeader("Content-Type", "application/json");
2076
- res.end(JSON.stringify({ error: "Invalid signature" }));
2077
- return;
2078
- }
2079
- if (match.kind === "ambiguous") {
2080
- logVerbose("line: webhook signature matched multiple accounts");
2081
- res.statusCode = 401;
2082
- res.setHeader("Content-Type", "application/json");
2083
- res.end(JSON.stringify({ error: "Ambiguous webhook target" }));
2084
- return;
2085
- }
2086
- const body = parseLineWebhookBody(rawBody);
2087
- if (!body) {
2088
- res.statusCode = 400;
2089
- res.setHeader("Content-Type", "application/json");
2090
- res.end(JSON.stringify({ error: "Invalid webhook payload" }));
2091
- return;
2092
- }
2093
- if (body.events && body.events.length > 0) {
2094
- logVerbose(`line: received ${body.events.length} webhook events`);
2095
- if (await match.target.bot.handleWebhook(body) === "durable") res.setHeader("x-openclaw-delivery-accepted", "durable");
2096
- }
2097
- res.statusCode = 200;
2098
- res.setHeader("Content-Type", "application/json");
2099
- res.end(JSON.stringify({ status: "ok" }));
2100
- } catch (err) {
2101
- if (await rejectLineWebhookRequest(req, res, err)) return;
2102
- runtime.error?.(danger(`line webhook error: ${formatErrorMessage(err)}`));
2103
- if (!res.headersSent) {
2104
- res.statusCode = 500;
2105
- res.setHeader("Content-Type", "application/json");
2106
- res.end(JSON.stringify({ error: "Internal server error" }));
2107
- }
2035
+ await handleWebhook(req, res);
2108
2036
  } finally {
2109
2037
  requestLifecycle.release();
2110
2038
  }
@@ -2143,4 +2071,4 @@ async function monitorLineProvider(opts) {
2143
2071
  };
2144
2072
  }
2145
2073
  //#endregion
2146
- export { resolveLineWebhookPath as a, parseLineWebhookBody as i, createLineNodeWebhookHandler as n, validateLineSignature as o, readLineWebhookRequestBody as r, downloadLineMedia as s, monitorLineProvider as t };
2074
+ export { monitorLineProvider as t };