@lark-project/openclaw-lark-project 2026.3.131

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 (368) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +80 -0
  3. package/README.zh.md +80 -0
  4. package/dist/index.js +172 -0
  5. package/dist/index.js.map +7 -0
  6. package/dist/skills/feishu-bitable/SKILL.md +248 -0
  7. package/dist/skills/feishu-bitable/references/examples.md +813 -0
  8. package/dist/skills/feishu-bitable/references/field-properties.md +763 -0
  9. package/dist/skills/feishu-bitable/references/record-values.md +911 -0
  10. package/dist/skills/feishu-calendar/SKILL.md +244 -0
  11. package/dist/skills/feishu-channel-rules/SKILL.md +18 -0
  12. package/dist/skills/feishu-channel-rules/references/markdown-syntax.md +138 -0
  13. package/dist/skills/feishu-create-doc/SKILL.md +719 -0
  14. package/dist/skills/feishu-fetch-doc/SKILL.md +93 -0
  15. package/dist/skills/feishu-im-read/SKILL.md +163 -0
  16. package/dist/skills/feishu-project/SKILL.md +122 -0
  17. package/dist/skills/feishu-task/SKILL.md +293 -0
  18. package/dist/skills/feishu-troubleshoot/SKILL.md +70 -0
  19. package/dist/skills/feishu-update-doc/SKILL.md +285 -0
  20. package/dist/src/card/builder.js +293 -0
  21. package/dist/src/card/builder.js.map +7 -0
  22. package/dist/src/card/cardkit.js +126 -0
  23. package/dist/src/card/cardkit.js.map +7 -0
  24. package/dist/src/card/flush-controller.js +107 -0
  25. package/dist/src/card/flush-controller.js.map +7 -0
  26. package/dist/src/card/markdown-style.js +57 -0
  27. package/dist/src/card/markdown-style.js.map +7 -0
  28. package/dist/src/card/reply-dispatcher-types.js +39 -0
  29. package/dist/src/card/reply-dispatcher-types.js.map +7 -0
  30. package/dist/src/card/reply-dispatcher.js +245 -0
  31. package/dist/src/card/reply-dispatcher.js.map +7 -0
  32. package/dist/src/card/reply-mode.js +29 -0
  33. package/dist/src/card/reply-mode.js.map +7 -0
  34. package/dist/src/card/streaming-card-controller.js +653 -0
  35. package/dist/src/card/streaming-card-controller.js.map +7 -0
  36. package/dist/src/card/unavailable-guard.js +76 -0
  37. package/dist/src/card/unavailable-guard.js.map +7 -0
  38. package/dist/src/channel/abort-detect.js +79 -0
  39. package/dist/src/channel/abort-detect.js.map +7 -0
  40. package/dist/src/channel/chat-queue.js +50 -0
  41. package/dist/src/channel/chat-queue.js.map +7 -0
  42. package/dist/src/channel/config-adapter.js +89 -0
  43. package/dist/src/channel/config-adapter.js.map +7 -0
  44. package/dist/src/channel/directory.js +133 -0
  45. package/dist/src/channel/directory.js.map +7 -0
  46. package/dist/src/channel/event-handlers.js +175 -0
  47. package/dist/src/channel/event-handlers.js.map +7 -0
  48. package/dist/src/channel/monitor.js +108 -0
  49. package/dist/src/channel/monitor.js.map +7 -0
  50. package/dist/src/channel/onboarding-config.js +76 -0
  51. package/dist/src/channel/onboarding-config.js.map +7 -0
  52. package/dist/src/channel/onboarding-migrate.js +55 -0
  53. package/dist/src/channel/onboarding-migrate.js.map +7 -0
  54. package/dist/src/channel/onboarding.js +285 -0
  55. package/dist/src/channel/onboarding.js.map +7 -0
  56. package/dist/src/channel/plugin.js +260 -0
  57. package/dist/src/channel/plugin.js.map +7 -0
  58. package/dist/src/channel/probe.js +14 -0
  59. package/dist/src/channel/probe.js.map +7 -0
  60. package/dist/src/channel/types.js +1 -0
  61. package/dist/src/channel/types.js.map +7 -0
  62. package/dist/src/commands/auth.js +73 -0
  63. package/dist/src/commands/auth.js.map +7 -0
  64. package/dist/src/commands/diagnose.js +658 -0
  65. package/dist/src/commands/diagnose.js.map +7 -0
  66. package/dist/src/commands/doctor.js +327 -0
  67. package/dist/src/commands/doctor.js.map +7 -0
  68. package/dist/src/commands/index.js +124 -0
  69. package/dist/src/commands/index.js.map +7 -0
  70. package/dist/src/core/accounts.js +129 -0
  71. package/dist/src/core/accounts.js.map +7 -0
  72. package/dist/src/core/agent-config.js +60 -0
  73. package/dist/src/core/agent-config.js.map +7 -0
  74. package/dist/src/core/api-error.js +55 -0
  75. package/dist/src/core/api-error.js.map +7 -0
  76. package/dist/src/core/app-owner-fallback.js +17 -0
  77. package/dist/src/core/app-owner-fallback.js.map +7 -0
  78. package/dist/src/core/app-scope-checker.js +95 -0
  79. package/dist/src/core/app-scope-checker.js.map +7 -0
  80. package/dist/src/core/auth-errors.js +120 -0
  81. package/dist/src/core/auth-errors.js.map +7 -0
  82. package/dist/src/core/chat-info-cache.js +102 -0
  83. package/dist/src/core/chat-info-cache.js.map +7 -0
  84. package/dist/src/core/config-schema.js +150 -0
  85. package/dist/src/core/config-schema.js.map +7 -0
  86. package/dist/src/core/device-flow.js +174 -0
  87. package/dist/src/core/device-flow.js.map +7 -0
  88. package/dist/src/core/feishu-fetch.js +12 -0
  89. package/dist/src/core/feishu-fetch.js.map +7 -0
  90. package/dist/src/core/footer-config.js +16 -0
  91. package/dist/src/core/footer-config.js.map +7 -0
  92. package/dist/src/core/lark-client.js +322 -0
  93. package/dist/src/core/lark-client.js.map +7 -0
  94. package/dist/src/core/lark-logger.js +92 -0
  95. package/dist/src/core/lark-logger.js.map +7 -0
  96. package/dist/src/core/lark-ticket.js +18 -0
  97. package/dist/src/core/lark-ticket.js.map +7 -0
  98. package/dist/src/core/message-unavailable.js +119 -0
  99. package/dist/src/core/message-unavailable.js.map +7 -0
  100. package/dist/src/core/owner-policy.js +25 -0
  101. package/dist/src/core/owner-policy.js.map +7 -0
  102. package/dist/src/core/permission-url.js +37 -0
  103. package/dist/src/core/permission-url.js.map +7 -0
  104. package/dist/src/core/project-auth.js +177 -0
  105. package/dist/src/core/project-auth.js.map +7 -0
  106. package/dist/src/core/project-oauth-flow.js +124 -0
  107. package/dist/src/core/project-oauth-flow.js.map +7 -0
  108. package/dist/src/core/project-token-store.js +172 -0
  109. package/dist/src/core/project-token-store.js.map +7 -0
  110. package/dist/src/core/raw-request.js +45 -0
  111. package/dist/src/core/raw-request.js.map +7 -0
  112. package/dist/src/core/scope-manager.js +62 -0
  113. package/dist/src/core/scope-manager.js.map +7 -0
  114. package/dist/src/core/security-check.js +118 -0
  115. package/dist/src/core/security-check.js.map +7 -0
  116. package/dist/src/core/shutdown-hooks.js +37 -0
  117. package/dist/src/core/shutdown-hooks.js.map +7 -0
  118. package/dist/src/core/targets.js +55 -0
  119. package/dist/src/core/targets.js.map +7 -0
  120. package/dist/src/core/token-store.js +215 -0
  121. package/dist/src/core/token-store.js.map +7 -0
  122. package/dist/src/core/tool-client.js +335 -0
  123. package/dist/src/core/tool-client.js.map +7 -0
  124. package/dist/src/core/tool-scopes.js +207 -0
  125. package/dist/src/core/tool-scopes.js.map +7 -0
  126. package/dist/src/core/tools-config.js +57 -0
  127. package/dist/src/core/tools-config.js.map +7 -0
  128. package/dist/src/core/types.js +1 -0
  129. package/dist/src/core/types.js.map +7 -0
  130. package/dist/src/core/uat-client.js +124 -0
  131. package/dist/src/core/uat-client.js.map +7 -0
  132. package/dist/src/core/version.js +27 -0
  133. package/dist/src/core/version.js.map +7 -0
  134. package/dist/src/messaging/converters/audio.js +19 -0
  135. package/dist/src/messaging/converters/audio.js.map +7 -0
  136. package/dist/src/messaging/converters/calendar.js +46 -0
  137. package/dist/src/messaging/converters/calendar.js.map +7 -0
  138. package/dist/src/messaging/converters/content-converter.js +61 -0
  139. package/dist/src/messaging/converters/content-converter.js.map +7 -0
  140. package/dist/src/messaging/converters/file.js +18 -0
  141. package/dist/src/messaging/converters/file.js.map +7 -0
  142. package/dist/src/messaging/converters/folder.js +18 -0
  143. package/dist/src/messaging/converters/folder.js.map +7 -0
  144. package/dist/src/messaging/converters/hongbao.js +14 -0
  145. package/dist/src/messaging/converters/hongbao.js.map +7 -0
  146. package/dist/src/messaging/converters/image.js +16 -0
  147. package/dist/src/messaging/converters/image.js.map +7 -0
  148. package/dist/src/messaging/converters/index.js +48 -0
  149. package/dist/src/messaging/converters/index.js.map +7 -0
  150. package/dist/src/messaging/converters/interactive/card-converter.js +1040 -0
  151. package/dist/src/messaging/converters/interactive/card-converter.js.map +7 -0
  152. package/dist/src/messaging/converters/interactive/card-utils.js +36 -0
  153. package/dist/src/messaging/converters/interactive/card-utils.js.map +7 -0
  154. package/dist/src/messaging/converters/interactive/index.js +19 -0
  155. package/dist/src/messaging/converters/interactive/index.js.map +7 -0
  156. package/dist/src/messaging/converters/interactive/legacy.js +53 -0
  157. package/dist/src/messaging/converters/interactive/legacy.js.map +7 -0
  158. package/dist/src/messaging/converters/interactive/types.js +23 -0
  159. package/dist/src/messaging/converters/interactive/types.js.map +7 -0
  160. package/dist/src/messaging/converters/location.js +17 -0
  161. package/dist/src/messaging/converters/location.js.map +7 -0
  162. package/dist/src/messaging/converters/merge-forward.js +143 -0
  163. package/dist/src/messaging/converters/merge-forward.js.map +7 -0
  164. package/dist/src/messaging/converters/post.js +113 -0
  165. package/dist/src/messaging/converters/post.js.map +7 -0
  166. package/dist/src/messaging/converters/share.js +22 -0
  167. package/dist/src/messaging/converters/share.js.map +7 -0
  168. package/dist/src/messaging/converters/sticker.js +16 -0
  169. package/dist/src/messaging/converters/sticker.js.map +7 -0
  170. package/dist/src/messaging/converters/system.js +25 -0
  171. package/dist/src/messaging/converters/system.js.map +7 -0
  172. package/dist/src/messaging/converters/text.js +12 -0
  173. package/dist/src/messaging/converters/text.js.map +7 -0
  174. package/dist/src/messaging/converters/todo.js +37 -0
  175. package/dist/src/messaging/converters/todo.js.map +7 -0
  176. package/dist/src/messaging/converters/types.js +1 -0
  177. package/dist/src/messaging/converters/types.js.map +7 -0
  178. package/dist/src/messaging/converters/unknown.js +13 -0
  179. package/dist/src/messaging/converters/unknown.js.map +7 -0
  180. package/dist/src/messaging/converters/utils.js +35 -0
  181. package/dist/src/messaging/converters/utils.js.map +7 -0
  182. package/dist/src/messaging/converters/video-chat.js +21 -0
  183. package/dist/src/messaging/converters/video-chat.js.map +7 -0
  184. package/dist/src/messaging/converters/video.js +30 -0
  185. package/dist/src/messaging/converters/video.js.map +7 -0
  186. package/dist/src/messaging/converters/vote.js +24 -0
  187. package/dist/src/messaging/converters/vote.js.map +7 -0
  188. package/dist/src/messaging/inbound/dedup.js +82 -0
  189. package/dist/src/messaging/inbound/dedup.js.map +7 -0
  190. package/dist/src/messaging/inbound/dispatch-builders.js +98 -0
  191. package/dist/src/messaging/inbound/dispatch-builders.js.map +7 -0
  192. package/dist/src/messaging/inbound/dispatch-commands.js +94 -0
  193. package/dist/src/messaging/inbound/dispatch-commands.js.map +7 -0
  194. package/dist/src/messaging/inbound/dispatch-context.js +96 -0
  195. package/dist/src/messaging/inbound/dispatch-context.js.map +7 -0
  196. package/dist/src/messaging/inbound/dispatch.js +150 -0
  197. package/dist/src/messaging/inbound/dispatch.js.map +7 -0
  198. package/dist/src/messaging/inbound/enrich.js +137 -0
  199. package/dist/src/messaging/inbound/enrich.js.map +7 -0
  200. package/dist/src/messaging/inbound/gate-effects.js +28 -0
  201. package/dist/src/messaging/inbound/gate-effects.js.map +7 -0
  202. package/dist/src/messaging/inbound/gate.js +163 -0
  203. package/dist/src/messaging/inbound/gate.js.map +7 -0
  204. package/dist/src/messaging/inbound/handler.js +132 -0
  205. package/dist/src/messaging/inbound/handler.js.map +7 -0
  206. package/dist/src/messaging/inbound/media-resolver.js +70 -0
  207. package/dist/src/messaging/inbound/media-resolver.js.map +7 -0
  208. package/dist/src/messaging/inbound/mention.js +50 -0
  209. package/dist/src/messaging/inbound/mention.js.map +7 -0
  210. package/dist/src/messaging/inbound/parse-io.js +41 -0
  211. package/dist/src/messaging/inbound/parse-io.js.map +7 -0
  212. package/dist/src/messaging/inbound/parse.js +79 -0
  213. package/dist/src/messaging/inbound/parse.js.map +7 -0
  214. package/dist/src/messaging/inbound/permission.js +30 -0
  215. package/dist/src/messaging/inbound/permission.js.map +7 -0
  216. package/dist/src/messaging/inbound/policy.js +83 -0
  217. package/dist/src/messaging/inbound/policy.js.map +7 -0
  218. package/dist/src/messaging/inbound/reaction-handler.js +162 -0
  219. package/dist/src/messaging/inbound/reaction-handler.js.map +7 -0
  220. package/dist/src/messaging/inbound/user-name-cache.js +172 -0
  221. package/dist/src/messaging/inbound/user-name-cache.js.map +7 -0
  222. package/dist/src/messaging/outbound/actions.js +239 -0
  223. package/dist/src/messaging/outbound/actions.js.map +7 -0
  224. package/dist/src/messaging/outbound/chat-manage.js +74 -0
  225. package/dist/src/messaging/outbound/chat-manage.js.map +7 -0
  226. package/dist/src/messaging/outbound/deliver.js +162 -0
  227. package/dist/src/messaging/outbound/deliver.js.map +7 -0
  228. package/dist/src/messaging/outbound/fetch.js +7 -0
  229. package/dist/src/messaging/outbound/fetch.js.map +7 -0
  230. package/dist/src/messaging/outbound/forward.js +31 -0
  231. package/dist/src/messaging/outbound/forward.js.map +7 -0
  232. package/dist/src/messaging/outbound/media-url-utils.js +101 -0
  233. package/dist/src/messaging/outbound/media-url-utils.js.map +7 -0
  234. package/dist/src/messaging/outbound/media.js +463 -0
  235. package/dist/src/messaging/outbound/media.js.map +7 -0
  236. package/dist/src/messaging/outbound/outbound.js +95 -0
  237. package/dist/src/messaging/outbound/outbound.js.map +7 -0
  238. package/dist/src/messaging/outbound/reactions.js +312 -0
  239. package/dist/src/messaging/outbound/reactions.js.map +7 -0
  240. package/dist/src/messaging/outbound/send.js +194 -0
  241. package/dist/src/messaging/outbound/send.js.map +7 -0
  242. package/dist/src/messaging/outbound/typing.js +77 -0
  243. package/dist/src/messaging/outbound/typing.js.map +7 -0
  244. package/dist/src/messaging/shared/message-lookup.js +84 -0
  245. package/dist/src/messaging/shared/message-lookup.js.map +7 -0
  246. package/dist/src/messaging/types.js +1 -0
  247. package/dist/src/messaging/types.js.map +7 -0
  248. package/dist/src/tools/auto-auth.js +714 -0
  249. package/dist/src/tools/auto-auth.js.map +7 -0
  250. package/dist/src/tools/helpers.js +133 -0
  251. package/dist/src/tools/helpers.js.map +7 -0
  252. package/dist/src/tools/mcp/doc/create.js +35 -0
  253. package/dist/src/tools/mcp/doc/create.js.map +7 -0
  254. package/dist/src/tools/mcp/doc/fetch.js +33 -0
  255. package/dist/src/tools/mcp/doc/fetch.js.map +7 -0
  256. package/dist/src/tools/mcp/doc/index.js +32 -0
  257. package/dist/src/tools/mcp/doc/index.js.map +7 -0
  258. package/dist/src/tools/mcp/doc/update.js +61 -0
  259. package/dist/src/tools/mcp/doc/update.js.map +7 -0
  260. package/dist/src/tools/mcp/project/endpoint.js +25 -0
  261. package/dist/src/tools/mcp/project/endpoint.js.map +7 -0
  262. package/dist/src/tools/mcp/project/index.js +27 -0
  263. package/dist/src/tools/mcp/project/index.js.map +7 -0
  264. package/dist/src/tools/mcp/project/tools.js +579 -0
  265. package/dist/src/tools/mcp/project/tools.js.map +7 -0
  266. package/dist/src/tools/mcp/shared.js +170 -0
  267. package/dist/src/tools/mcp/shared.js.map +7 -0
  268. package/dist/src/tools/oapi/bitable/app-table-field.js +244 -0
  269. package/dist/src/tools/oapi/bitable/app-table-field.js.map +7 -0
  270. package/dist/src/tools/oapi/bitable/app-table-record.js +501 -0
  271. package/dist/src/tools/oapi/bitable/app-table-record.js.map +7 -0
  272. package/dist/src/tools/oapi/bitable/app-table-view.js +226 -0
  273. package/dist/src/tools/oapi/bitable/app-table-view.js.map +7 -0
  274. package/dist/src/tools/oapi/bitable/app-table.js +278 -0
  275. package/dist/src/tools/oapi/bitable/app-table.js.map +7 -0
  276. package/dist/src/tools/oapi/bitable/app.js +200 -0
  277. package/dist/src/tools/oapi/bitable/app.js.map +7 -0
  278. package/dist/src/tools/oapi/bitable/index.js +13 -0
  279. package/dist/src/tools/oapi/bitable/index.js.map +7 -0
  280. package/dist/src/tools/oapi/calendar/calendar.js +131 -0
  281. package/dist/src/tools/oapi/calendar/calendar.js.map +7 -0
  282. package/dist/src/tools/oapi/calendar/event-attendee.js +301 -0
  283. package/dist/src/tools/oapi/calendar/event-attendee.js.map +7 -0
  284. package/dist/src/tools/oapi/calendar/event.js +834 -0
  285. package/dist/src/tools/oapi/calendar/event.js.map +7 -0
  286. package/dist/src/tools/oapi/calendar/freebusy.js +111 -0
  287. package/dist/src/tools/oapi/calendar/freebusy.js.map +7 -0
  288. package/dist/src/tools/oapi/calendar/index.js +11 -0
  289. package/dist/src/tools/oapi/calendar/index.js.map +7 -0
  290. package/dist/src/tools/oapi/chat/chat.js +132 -0
  291. package/dist/src/tools/oapi/chat/chat.js.map +7 -0
  292. package/dist/src/tools/oapi/chat/index.js +11 -0
  293. package/dist/src/tools/oapi/chat/index.js.map +7 -0
  294. package/dist/src/tools/oapi/chat/members.js +83 -0
  295. package/dist/src/tools/oapi/chat/members.js.map +7 -0
  296. package/dist/src/tools/oapi/common/get-user.js +95 -0
  297. package/dist/src/tools/oapi/common/get-user.js.map +7 -0
  298. package/dist/src/tools/oapi/common/index.js +7 -0
  299. package/dist/src/tools/oapi/common/index.js.map +7 -0
  300. package/dist/src/tools/oapi/common/search-user.js +67 -0
  301. package/dist/src/tools/oapi/common/search-user.js.map +7 -0
  302. package/dist/src/tools/oapi/drive/doc-comments.js +310 -0
  303. package/dist/src/tools/oapi/drive/doc-comments.js.map +7 -0
  304. package/dist/src/tools/oapi/drive/doc-media.js +314 -0
  305. package/dist/src/tools/oapi/drive/doc-media.js.map +7 -0
  306. package/dist/src/tools/oapi/drive/file.js +548 -0
  307. package/dist/src/tools/oapi/drive/file.js.map +7 -0
  308. package/dist/src/tools/oapi/drive/index.js +29 -0
  309. package/dist/src/tools/oapi/drive/index.js.map +7 -0
  310. package/dist/src/tools/oapi/helpers.js +199 -0
  311. package/dist/src/tools/oapi/helpers.js.map +7 -0
  312. package/dist/src/tools/oapi/im/format-messages.js +128 -0
  313. package/dist/src/tools/oapi/im/format-messages.js.map +7 -0
  314. package/dist/src/tools/oapi/im/index.js +15 -0
  315. package/dist/src/tools/oapi/im/index.js.map +7 -0
  316. package/dist/src/tools/oapi/im/message-read.js +404 -0
  317. package/dist/src/tools/oapi/im/message-read.js.map +7 -0
  318. package/dist/src/tools/oapi/im/message.js +179 -0
  319. package/dist/src/tools/oapi/im/message.js.map +7 -0
  320. package/dist/src/tools/oapi/im/resource.js +126 -0
  321. package/dist/src/tools/oapi/im/resource.js.map +7 -0
  322. package/dist/src/tools/oapi/im/time-utils.js +169 -0
  323. package/dist/src/tools/oapi/im/time-utils.js.map +7 -0
  324. package/dist/src/tools/oapi/im/user-name-uat.js +103 -0
  325. package/dist/src/tools/oapi/im/user-name-uat.js.map +7 -0
  326. package/dist/src/tools/oapi/index.js +56 -0
  327. package/dist/src/tools/oapi/index.js.map +7 -0
  328. package/dist/src/tools/oapi/sdk-types.js +1 -0
  329. package/dist/src/tools/oapi/sdk-types.js.map +7 -0
  330. package/dist/src/tools/oapi/search/doc-search.js +215 -0
  331. package/dist/src/tools/oapi/search/doc-search.js.map +7 -0
  332. package/dist/src/tools/oapi/search/index.js +25 -0
  333. package/dist/src/tools/oapi/search/index.js.map +7 -0
  334. package/dist/src/tools/oapi/sheets/index.js +25 -0
  335. package/dist/src/tools/oapi/sheets/index.js.map +7 -0
  336. package/dist/src/tools/oapi/sheets/sheet.js +652 -0
  337. package/dist/src/tools/oapi/sheets/sheet.js.map +7 -0
  338. package/dist/src/tools/oapi/task/comment.js +151 -0
  339. package/dist/src/tools/oapi/task/comment.js.map +7 -0
  340. package/dist/src/tools/oapi/task/index.js +11 -0
  341. package/dist/src/tools/oapi/task/index.js.map +7 -0
  342. package/dist/src/tools/oapi/task/subtask.js +175 -0
  343. package/dist/src/tools/oapi/task/subtask.js.map +7 -0
  344. package/dist/src/tools/oapi/task/task.js +405 -0
  345. package/dist/src/tools/oapi/task/task.js.map +7 -0
  346. package/dist/src/tools/oapi/task/tasklist.js +366 -0
  347. package/dist/src/tools/oapi/task/tasklist.js.map +7 -0
  348. package/dist/src/tools/oapi/wiki/index.js +27 -0
  349. package/dist/src/tools/oapi/wiki/index.js.map +7 -0
  350. package/dist/src/tools/oapi/wiki/space-node.js +311 -0
  351. package/dist/src/tools/oapi/wiki/space-node.js.map +7 -0
  352. package/dist/src/tools/oapi/wiki/space.js +148 -0
  353. package/dist/src/tools/oapi/wiki/space.js.map +7 -0
  354. package/dist/src/tools/oauth-batch-auth.js +125 -0
  355. package/dist/src/tools/oauth-batch-auth.js.map +7 -0
  356. package/dist/src/tools/oauth-cards.js +269 -0
  357. package/dist/src/tools/oauth-cards.js.map +7 -0
  358. package/dist/src/tools/oauth.js +538 -0
  359. package/dist/src/tools/oauth.js.map +7 -0
  360. package/dist/src/tools/onboarding-auth.js +101 -0
  361. package/dist/src/tools/onboarding-auth.js.map +7 -0
  362. package/dist/src/tools/project-oauth.js +305 -0
  363. package/dist/src/tools/project-oauth.js.map +7 -0
  364. package/dist/src/tools/tat/im/index.js +9 -0
  365. package/dist/src/tools/tat/im/index.js.map +7 -0
  366. package/dist/src/tools/tat/im/resource.js +123 -0
  367. package/dist/src/tools/tat/im/resource.js.map +7 -0
  368. package/package.json +64 -0
@@ -0,0 +1,653 @@
1
+ import { SILENT_REPLY_TOKEN } from "openclaw/plugin-sdk";
2
+ import { extractLarkApiCode } from "../core/api-error";
3
+ import { larkLogger } from "../core/lark-logger";
4
+ import { sendCardFeishu, updateCardFeishu } from "../messaging/outbound/send";
5
+ import {
6
+ createCardEntity,
7
+ sendCardByCardId,
8
+ streamCardContent,
9
+ updateCardKitCard,
10
+ setCardStreamingMode
11
+ } from "./cardkit";
12
+ import { buildCardContent, splitReasoningText, stripReasoningTags, STREAMING_ELEMENT_ID, toCardKit2 } from "./builder";
13
+ import { optimizeMarkdownStyle } from "./markdown-style";
14
+ import { registerShutdownHook } from "../core/shutdown-hooks";
15
+ import { FlushController } from "./flush-controller";
16
+ import { UnavailableGuard } from "./unavailable-guard";
17
+ import {
18
+ TERMINAL_PHASES,
19
+ PHASE_TRANSITIONS,
20
+ THROTTLE_CONSTANTS,
21
+ EMPTY_REPLY_FALLBACK_TEXT
22
+ } from "./reply-dispatcher-types";
23
+ const log = larkLogger("card/streaming");
24
+ const STREAMING_THINKING_CARD = {
25
+ schema: "2.0",
26
+ config: {
27
+ streaming_mode: true,
28
+ summary: { content: "\u601D\u8003\u4E2D..." }
29
+ },
30
+ body: {
31
+ elements: [
32
+ {
33
+ tag: "markdown",
34
+ content: "",
35
+ text_align: "left",
36
+ text_size: "normal_v2",
37
+ margin: "0px 0px 0px 0px",
38
+ element_id: STREAMING_ELEMENT_ID
39
+ },
40
+ {
41
+ tag: "markdown",
42
+ content: " ",
43
+ icon: {
44
+ tag: "custom_icon",
45
+ img_key: "img_v3_02vb_496bec09-4b43-4773-ad6b-0cdd103cd2bg",
46
+ size: "16px 16px"
47
+ },
48
+ element_id: "loading_icon"
49
+ }
50
+ ]
51
+ }
52
+ };
53
+ class StreamingCardController {
54
+ // ---- Explicit state machine ----
55
+ phase = "idle";
56
+ // ---- Structured state ----
57
+ cardKit = {
58
+ cardKitCardId: null,
59
+ originalCardKitCardId: null,
60
+ cardKitSequence: 0,
61
+ cardMessageId: null
62
+ };
63
+ text = {
64
+ accumulatedText: "",
65
+ completedText: "",
66
+ streamingPrefix: "",
67
+ lastPartialText: ""
68
+ };
69
+ reasoning = {
70
+ accumulatedReasoningText: "",
71
+ reasoningStartTime: null,
72
+ reasoningElapsedMs: 0,
73
+ isReasoningPhase: false
74
+ };
75
+ // ---- Sub-controllers ----
76
+ flush;
77
+ guard;
78
+ // ---- Lifecycle ----
79
+ createEpoch = 0;
80
+ _terminalReason = null;
81
+ dispatchFullyComplete = false;
82
+ cardCreationPromise = null;
83
+ disposeShutdownHook = null;
84
+ dispatchStartTime = Date.now();
85
+ // ---- Injected dependencies ----
86
+ deps;
87
+ elapsed() {
88
+ return Date.now() - this.dispatchStartTime;
89
+ }
90
+ constructor(deps) {
91
+ this.deps = deps;
92
+ this.guard = new UnavailableGuard({
93
+ replyToMessageId: deps.replyToMessageId,
94
+ getCardMessageId: () => this.cardKit.cardMessageId,
95
+ onTerminate: () => {
96
+ this.transition("terminated", "UnavailableGuard", "unavailable");
97
+ }
98
+ });
99
+ this.flush = new FlushController(() => this.performFlush());
100
+ }
101
+ // ------------------------------------------------------------------
102
+ // Public accessors
103
+ // ------------------------------------------------------------------
104
+ get cardMessageId() {
105
+ return this.cardKit.cardMessageId;
106
+ }
107
+ get isTerminalPhase() {
108
+ return TERMINAL_PHASES.has(this.phase);
109
+ }
110
+ /**
111
+ * Whether the card has been explicitly aborted (via abortCard()).
112
+ *
113
+ * Distinct from isTerminalPhase — creation_failed is NOT an abort;
114
+ * it should allow fallthrough to static delivery in the factory.
115
+ */
116
+ get isAborted() {
117
+ return this.phase === "aborted";
118
+ }
119
+ /** Whether the reply pipeline was terminated due to an unavailable message. */
120
+ get isTerminated() {
121
+ return this.guard.isTerminated;
122
+ }
123
+ /** Check if the pipeline should skip further operations for this source. */
124
+ shouldSkipForUnavailable(source) {
125
+ return this.guard.shouldSkip(source);
126
+ }
127
+ /** Attempt to terminate the pipeline due to an unavailable message error. */
128
+ terminateIfUnavailable(source, err) {
129
+ return this.guard.terminate(source, err);
130
+ }
131
+ /** Why the controller entered a terminal phase, or null if still active. */
132
+ get terminalReason() {
133
+ return this._terminalReason;
134
+ }
135
+ /** @internal — exposed for test assertions only. */
136
+ get currentPhase() {
137
+ return this.phase;
138
+ }
139
+ // ------------------------------------------------------------------
140
+ // Unified callback guard
141
+ // ------------------------------------------------------------------
142
+ /**
143
+ * Unified callback guard — returns true if the pipeline is active
144
+ * and the callback should proceed.
145
+ *
146
+ * Combines three checks:
147
+ * 1. guard.isTerminated — message recalled/deleted
148
+ * 2. guard.shouldSkip(source) — eagerly detect unavailable messages
149
+ * 3. isTerminalPhase — completed/aborted/terminated/creation_failed
150
+ */
151
+ shouldProceed(source) {
152
+ if (this.guard.isTerminated || this.guard.shouldSkip(source)) return false;
153
+ return !this.isTerminalPhase;
154
+ }
155
+ // ------------------------------------------------------------------
156
+ // State machine
157
+ // ------------------------------------------------------------------
158
+ isStaleCreate(epoch) {
159
+ return epoch !== this.createEpoch;
160
+ }
161
+ transition(to, source, reason) {
162
+ const from = this.phase;
163
+ if (from === to) return false;
164
+ if (!PHASE_TRANSITIONS[from].has(to)) {
165
+ log.warn("phase transition rejected", { from, to, source });
166
+ return false;
167
+ }
168
+ this.phase = to;
169
+ log.info("phase transition", { from, to, source, reason });
170
+ if (TERMINAL_PHASES.has(to)) {
171
+ this._terminalReason = reason ?? null;
172
+ this.onEnterTerminalPhase();
173
+ }
174
+ return true;
175
+ }
176
+ onEnterTerminalPhase() {
177
+ this.createEpoch += 1;
178
+ this.flush.cancelPendingFlush();
179
+ this.flush.complete();
180
+ this.disposeShutdownHook?.();
181
+ this.disposeShutdownHook = null;
182
+ }
183
+ // ------------------------------------------------------------------
184
+ // SDK callback bindings
185
+ // ------------------------------------------------------------------
186
+ /**
187
+ * Handle a deliver() call in streaming card mode.
188
+ *
189
+ * Accumulates text from the SDK's deliver callbacks to build the
190
+ * authoritative "completedText" for the final card.
191
+ */
192
+ async onDeliver(payload) {
193
+ if (!this.shouldProceed("onDeliver")) return;
194
+ const text = payload.text ?? "";
195
+ if (!text.trim()) return;
196
+ await this.ensureCardCreated();
197
+ if (!this.shouldProceed("onDeliver.postCreate")) return;
198
+ if (!this.cardKit.cardMessageId) return;
199
+ const split = splitReasoningText(text);
200
+ if (split.reasoningText && !split.answerText) {
201
+ this.reasoning.reasoningElapsedMs = this.reasoning.reasoningStartTime ? Date.now() - this.reasoning.reasoningStartTime : 0;
202
+ this.reasoning.accumulatedReasoningText = split.reasoningText;
203
+ this.reasoning.isReasoningPhase = true;
204
+ await this.throttledCardUpdate();
205
+ return;
206
+ }
207
+ this.reasoning.isReasoningPhase = false;
208
+ if (split.reasoningText) {
209
+ this.reasoning.accumulatedReasoningText = split.reasoningText;
210
+ }
211
+ const answerText = split.answerText ?? text;
212
+ this.text.completedText += (this.text.completedText ? "\n\n" : "") + answerText;
213
+ if (!this.text.lastPartialText && !this.text.streamingPrefix) {
214
+ this.text.accumulatedText += (this.text.accumulatedText ? "\n\n" : "") + answerText;
215
+ this.text.streamingPrefix = this.text.accumulatedText;
216
+ await this.throttledCardUpdate();
217
+ }
218
+ }
219
+ async onReasoningStream(payload) {
220
+ if (!this.shouldProceed("onReasoningStream")) return;
221
+ await this.ensureCardCreated();
222
+ if (!this.shouldProceed("onReasoningStream.postCreate")) return;
223
+ if (!this.cardKit.cardMessageId) return;
224
+ const rawText = payload.text ?? "";
225
+ if (!rawText) return;
226
+ if (!this.reasoning.reasoningStartTime) {
227
+ this.reasoning.reasoningStartTime = Date.now();
228
+ }
229
+ this.reasoning.isReasoningPhase = true;
230
+ const split = splitReasoningText(rawText);
231
+ this.reasoning.accumulatedReasoningText = split.reasoningText ?? rawText;
232
+ await this.throttledCardUpdate();
233
+ }
234
+ async onPartialReply(payload) {
235
+ if (!this.shouldProceed("onPartialReply")) return;
236
+ const text = stripReasoningTags(payload.text ?? "");
237
+ log.debug("onPartialReply", { len: text.length });
238
+ if (!text) return;
239
+ if (!this.reasoning.reasoningStartTime) {
240
+ this.reasoning.reasoningStartTime = Date.now();
241
+ }
242
+ if (this.reasoning.isReasoningPhase) {
243
+ this.reasoning.isReasoningPhase = false;
244
+ this.reasoning.reasoningElapsedMs = this.reasoning.reasoningStartTime ? Date.now() - this.reasoning.reasoningStartTime : 0;
245
+ }
246
+ if (this.text.lastPartialText && text.length < this.text.lastPartialText.length) {
247
+ this.text.streamingPrefix += (this.text.streamingPrefix ? "\n\n" : "") + this.text.lastPartialText;
248
+ }
249
+ this.text.lastPartialText = text;
250
+ this.text.accumulatedText = this.text.streamingPrefix ? this.text.streamingPrefix + "\n\n" + text : text;
251
+ if (!this.text.streamingPrefix && SILENT_REPLY_TOKEN.startsWith(this.text.accumulatedText.trim())) {
252
+ log.debug("onPartialReply: buffering NO_REPLY prefix");
253
+ return;
254
+ }
255
+ await this.ensureCardCreated();
256
+ if (!this.shouldProceed("onPartialReply.postCreate")) return;
257
+ if (!this.cardKit.cardMessageId) return;
258
+ await this.throttledCardUpdate();
259
+ }
260
+ async onError(err, info) {
261
+ if (this.guard.terminate("onError", err)) return;
262
+ log.error(`${info.kind} reply failed`, { error: String(err) });
263
+ this.finalizeCard("onError", "error");
264
+ await this.flush.waitForFlush();
265
+ if (this.cardCreationPromise) await this.cardCreationPromise;
266
+ const errorEffectiveCardId = this.cardKit.cardKitCardId ?? this.cardKit.originalCardKitCardId;
267
+ if (this.cardKit.cardMessageId) {
268
+ try {
269
+ const errorText = this.text.accumulatedText ? `${this.text.accumulatedText}
270
+
271
+ ---
272
+ **Error**: An error occurred while generating the response.` : "**Error**: An error occurred while generating the response.";
273
+ const errorCard = buildCardContent("complete", {
274
+ text: errorText,
275
+ reasoningText: this.reasoning.accumulatedReasoningText || void 0,
276
+ reasoningElapsedMs: this.reasoning.reasoningElapsedMs || void 0,
277
+ elapsedMs: this.elapsed(),
278
+ isError: true,
279
+ footer: this.deps.resolvedFooter
280
+ });
281
+ if (errorEffectiveCardId) {
282
+ await this.closeStreamingAndUpdate(errorEffectiveCardId, errorCard, "onError");
283
+ } else {
284
+ await updateCardFeishu({
285
+ cfg: this.deps.cfg,
286
+ messageId: this.cardKit.cardMessageId,
287
+ card: errorCard,
288
+ accountId: this.deps.accountId
289
+ });
290
+ }
291
+ } catch {
292
+ }
293
+ }
294
+ }
295
+ async onIdle() {
296
+ if (this.guard.isTerminated || this.guard.shouldSkip("onIdle")) return;
297
+ if (!this.dispatchFullyComplete) return;
298
+ if (this.isTerminalPhase) return;
299
+ this.finalizeCard("onIdle", "normal");
300
+ await this.flush.waitForFlush();
301
+ if (this.cardCreationPromise) {
302
+ await this.cardCreationPromise;
303
+ await new Promise((resolve) => setTimeout(resolve, 0));
304
+ await this.flush.waitForFlush();
305
+ }
306
+ const idleEffectiveCardId = this.cardKit.cardKitCardId ?? this.cardKit.originalCardKitCardId;
307
+ if (this.cardKit.cardMessageId) {
308
+ try {
309
+ if (idleEffectiveCardId) {
310
+ const seqBeforeClose = this.cardKit.cardKitSequence;
311
+ this.cardKit.cardKitSequence += 1;
312
+ log.info("onIdle: closing streaming mode", {
313
+ seqBefore: seqBeforeClose,
314
+ seqAfter: this.cardKit.cardKitSequence
315
+ });
316
+ await setCardStreamingMode({
317
+ cfg: this.deps.cfg,
318
+ cardId: idleEffectiveCardId,
319
+ streamingMode: false,
320
+ sequence: this.cardKit.cardKitSequence,
321
+ accountId: this.deps.accountId
322
+ });
323
+ }
324
+ const isNoReplyLeak = !this.text.completedText && SILENT_REPLY_TOKEN.startsWith(this.text.accumulatedText.trim());
325
+ const displayText = this.text.completedText || (isNoReplyLeak ? "" : this.text.accumulatedText) || EMPTY_REPLY_FALLBACK_TEXT;
326
+ if (!this.text.completedText && !this.text.accumulatedText) {
327
+ log.warn("reply completed without visible text, using empty-reply fallback");
328
+ }
329
+ const completeCard = buildCardContent("complete", {
330
+ text: displayText,
331
+ reasoningText: this.reasoning.accumulatedReasoningText || void 0,
332
+ reasoningElapsedMs: this.reasoning.reasoningElapsedMs || void 0,
333
+ elapsedMs: this.elapsed(),
334
+ footer: this.deps.resolvedFooter
335
+ });
336
+ if (idleEffectiveCardId) {
337
+ const seqBeforeUpdate = this.cardKit.cardKitSequence;
338
+ this.cardKit.cardKitSequence += 1;
339
+ log.info("onIdle: updating final card", {
340
+ seqBefore: seqBeforeUpdate,
341
+ seqAfter: this.cardKit.cardKitSequence
342
+ });
343
+ await updateCardKitCard({
344
+ cfg: this.deps.cfg,
345
+ cardId: idleEffectiveCardId,
346
+ card: toCardKit2(completeCard),
347
+ sequence: this.cardKit.cardKitSequence,
348
+ accountId: this.deps.accountId
349
+ });
350
+ } else {
351
+ await updateCardFeishu({
352
+ cfg: this.deps.cfg,
353
+ messageId: this.cardKit.cardMessageId,
354
+ card: completeCard,
355
+ accountId: this.deps.accountId
356
+ });
357
+ }
358
+ log.info("reply completed, card finalized", {
359
+ elapsedMs: this.elapsed(),
360
+ isCardKit: !!idleEffectiveCardId
361
+ });
362
+ } catch (err) {
363
+ log.warn("final card update failed", { error: String(err) });
364
+ }
365
+ }
366
+ }
367
+ // ------------------------------------------------------------------
368
+ // External control
369
+ // ------------------------------------------------------------------
370
+ markFullyComplete() {
371
+ log.debug("markFullyComplete", {
372
+ completedTextLen: this.text.completedText.length,
373
+ accumulatedTextLen: this.text.accumulatedText.length
374
+ });
375
+ this.dispatchFullyComplete = true;
376
+ }
377
+ async abortCard() {
378
+ try {
379
+ if (!this.transition("aborted", "abortCard", "abort")) return;
380
+ await this.flush.waitForFlush();
381
+ if (this.cardCreationPromise) await this.cardCreationPromise;
382
+ const effectiveCardId = this.cardKit.cardKitCardId ?? this.cardKit.originalCardKitCardId;
383
+ if (effectiveCardId) {
384
+ const elapsedMs = Date.now() - this.dispatchStartTime;
385
+ const abortText = this.text.accumulatedText || "Aborted.";
386
+ const abortCardContent = buildCardContent("complete", {
387
+ text: abortText,
388
+ reasoningText: this.reasoning.accumulatedReasoningText || void 0,
389
+ reasoningElapsedMs: this.reasoning.reasoningElapsedMs || void 0,
390
+ elapsedMs,
391
+ isAborted: true,
392
+ footer: this.deps.resolvedFooter
393
+ });
394
+ await this.closeStreamingAndUpdate(effectiveCardId, abortCardContent, "abortCard");
395
+ log.info("abortCard completed", { effectiveCardId });
396
+ } else if (this.cardKit.cardMessageId) {
397
+ const elapsedMs = Date.now() - this.dispatchStartTime;
398
+ const abortText = this.text.accumulatedText || "Aborted.";
399
+ const abortCard = buildCardContent("complete", {
400
+ text: abortText,
401
+ reasoningText: this.reasoning.accumulatedReasoningText || void 0,
402
+ reasoningElapsedMs: this.reasoning.reasoningElapsedMs || void 0,
403
+ elapsedMs,
404
+ isAborted: true,
405
+ footer: this.deps.resolvedFooter
406
+ });
407
+ await updateCardFeishu({
408
+ cfg: this.deps.cfg,
409
+ messageId: this.cardKit.cardMessageId,
410
+ card: abortCard,
411
+ accountId: this.deps.accountId
412
+ });
413
+ log.info("abortCard completed (IM fallback)", { messageId: this.cardKit.cardMessageId });
414
+ }
415
+ } catch (err) {
416
+ log.warn("abortCard failed", { error: String(err) });
417
+ }
418
+ }
419
+ // ------------------------------------------------------------------
420
+ // Internal: card creation
421
+ // ------------------------------------------------------------------
422
+ async ensureCardCreated() {
423
+ if (this.guard.shouldSkip("ensureCardCreated.precheck")) return;
424
+ if (this.cardKit.cardMessageId || this.phase === "creation_failed" || this.isTerminalPhase) {
425
+ return;
426
+ }
427
+ if (this.cardCreationPromise) {
428
+ await this.cardCreationPromise;
429
+ return;
430
+ }
431
+ if (!this.transition("creating", "ensureCardCreated")) return;
432
+ this.createEpoch += 1;
433
+ const epoch = this.createEpoch;
434
+ this.cardCreationPromise = (async () => {
435
+ try {
436
+ try {
437
+ const cId = await createCardEntity({
438
+ cfg: this.deps.cfg,
439
+ card: STREAMING_THINKING_CARD,
440
+ accountId: this.deps.accountId
441
+ });
442
+ if (this.isStaleCreate(epoch)) {
443
+ log.info("ensureCardCreated: stale epoch after createCardEntity, bailing out", {
444
+ epoch,
445
+ phase: this.phase
446
+ });
447
+ return;
448
+ }
449
+ if (cId) {
450
+ this.cardKit.cardKitCardId = cId;
451
+ this.cardKit.originalCardKitCardId = cId;
452
+ this.cardKit.cardKitSequence = 1;
453
+ this.disposeShutdownHook = registerShutdownHook(`streaming-card:${cId}`, () => this.abortCard());
454
+ log.info("created CardKit entity", {
455
+ cardId: cId,
456
+ initialSequence: this.cardKit.cardKitSequence
457
+ });
458
+ const result = await sendCardByCardId({
459
+ cfg: this.deps.cfg,
460
+ to: this.deps.chatId,
461
+ cardId: cId,
462
+ replyToMessageId: this.deps.replyToMessageId,
463
+ replyInThread: this.deps.replyInThread,
464
+ accountId: this.deps.accountId
465
+ });
466
+ if (this.isStaleCreate(epoch)) {
467
+ log.info("ensureCardCreated: stale epoch after sendCardByCardId, bailing out", {
468
+ epoch,
469
+ phase: this.phase
470
+ });
471
+ this.disposeShutdownHook?.();
472
+ this.disposeShutdownHook = null;
473
+ return;
474
+ }
475
+ this.cardKit.cardMessageId = result.messageId;
476
+ this.flush.setCardMessageReady(true);
477
+ if (!this.transition("streaming", "ensureCardCreated.cardkit")) {
478
+ this.disposeShutdownHook?.();
479
+ this.disposeShutdownHook = null;
480
+ return;
481
+ }
482
+ log.info("sent CardKit card", { messageId: result.messageId });
483
+ } else {
484
+ throw new Error("card.create returned empty card_id");
485
+ }
486
+ } catch (cardKitErr) {
487
+ if (this.isStaleCreate(epoch)) return;
488
+ if (this.guard.terminate("ensureCardCreated.cardkitFlow", cardKitErr)) {
489
+ return;
490
+ }
491
+ const apiDetail = extractApiDetail(cardKitErr);
492
+ log.warn("CardKit flow failed, falling back to IM", { apiDetail });
493
+ this.cardKit.cardKitCardId = null;
494
+ this.cardKit.originalCardKitCardId = null;
495
+ const fallbackCard = buildCardContent("thinking");
496
+ const result = await sendCardFeishu({
497
+ cfg: this.deps.cfg,
498
+ to: this.deps.chatId,
499
+ card: fallbackCard,
500
+ replyToMessageId: this.deps.replyToMessageId,
501
+ replyInThread: this.deps.replyInThread,
502
+ accountId: this.deps.accountId
503
+ });
504
+ if (this.isStaleCreate(epoch)) {
505
+ log.info("ensureCardCreated: stale epoch after IM fallback send, bailing out", {
506
+ epoch,
507
+ phase: this.phase
508
+ });
509
+ return;
510
+ }
511
+ this.cardKit.cardMessageId = result.messageId;
512
+ this.flush.setCardMessageReady(true);
513
+ if (!this.transition("streaming", "ensureCardCreated.imFallback")) {
514
+ return;
515
+ }
516
+ log.info("sent fallback IM card", { messageId: result.messageId });
517
+ }
518
+ } catch (err) {
519
+ if (this.isStaleCreate(epoch)) return;
520
+ if (this.guard.terminate("ensureCardCreated.outer", err)) {
521
+ return;
522
+ }
523
+ log.warn("thinking card failed, falling back to static", { error: String(err) });
524
+ this.transition("creation_failed", "ensureCardCreated.outer", "creation_failed");
525
+ }
526
+ })();
527
+ await this.cardCreationPromise;
528
+ }
529
+ // ------------------------------------------------------------------
530
+ // Internal: flush
531
+ // ------------------------------------------------------------------
532
+ async performFlush() {
533
+ if (!this.cardKit.cardMessageId || this.isTerminalPhase) return;
534
+ if (!this.cardKit.cardKitCardId && this.cardKit.originalCardKitCardId) {
535
+ log.debug("performFlush: skipping (CardKit streaming disabled, awaiting final update)");
536
+ return;
537
+ }
538
+ log.debug("flushCardUpdate: enter", {
539
+ seq: this.cardKit.cardKitSequence,
540
+ isCardKit: !!this.cardKit.cardKitCardId
541
+ });
542
+ try {
543
+ const displayText = this.buildDisplayText();
544
+ if (this.cardKit.cardKitCardId) {
545
+ const prevSeq = this.cardKit.cardKitSequence;
546
+ this.cardKit.cardKitSequence += 1;
547
+ log.debug("flushCardUpdate: seq bump", {
548
+ seqBefore: prevSeq,
549
+ seqAfter: this.cardKit.cardKitSequence
550
+ });
551
+ await streamCardContent({
552
+ cfg: this.deps.cfg,
553
+ cardId: this.cardKit.cardKitCardId,
554
+ elementId: STREAMING_ELEMENT_ID,
555
+ content: optimizeMarkdownStyle(displayText),
556
+ sequence: this.cardKit.cardKitSequence,
557
+ accountId: this.deps.accountId
558
+ });
559
+ } else {
560
+ log.debug("flushCardUpdate: IM patch fallback");
561
+ const card = buildCardContent("streaming", {
562
+ text: this.reasoning.isReasoningPhase ? "" : displayText,
563
+ reasoningText: this.reasoning.isReasoningPhase ? this.reasoning.accumulatedReasoningText : void 0
564
+ });
565
+ await updateCardFeishu({
566
+ cfg: this.deps.cfg,
567
+ messageId: this.cardKit.cardMessageId,
568
+ card,
569
+ accountId: this.deps.accountId
570
+ });
571
+ }
572
+ } catch (err) {
573
+ if (this.guard.terminate("flushCardUpdate", err)) return;
574
+ const apiCode = extractLarkApiCode(err);
575
+ if (apiCode === 230020) {
576
+ log.info("flushCardUpdate: rate limited (230020), skipping", {
577
+ seq: this.cardKit.cardKitSequence
578
+ });
579
+ return;
580
+ }
581
+ const apiDetail = extractApiDetail(err);
582
+ log.error("card stream update failed", {
583
+ apiCode,
584
+ seq: this.cardKit.cardKitSequence,
585
+ apiDetail
586
+ });
587
+ if (this.cardKit.cardKitCardId) {
588
+ log.warn("disabling CardKit streaming, falling back to im.message.patch");
589
+ this.cardKit.cardKitCardId = null;
590
+ }
591
+ }
592
+ }
593
+ buildDisplayText() {
594
+ if (this.reasoning.isReasoningPhase && this.reasoning.accumulatedReasoningText) {
595
+ const reasoningDisplay = `\u{1F4AD} **Thinking...**
596
+
597
+ ${this.reasoning.accumulatedReasoningText}`;
598
+ return this.text.accumulatedText ? this.text.accumulatedText + "\n\n" + reasoningDisplay : reasoningDisplay;
599
+ }
600
+ return this.text.accumulatedText;
601
+ }
602
+ async throttledCardUpdate() {
603
+ if (this.guard.shouldSkip("throttledCardUpdate")) return;
604
+ const throttleMs = this.cardKit.cardKitCardId ? THROTTLE_CONSTANTS.CARDKIT_MS : THROTTLE_CONSTANTS.PATCH_MS;
605
+ await this.flush.throttledUpdate(throttleMs);
606
+ }
607
+ // ------------------------------------------------------------------
608
+ // Internal: lifecycle helpers
609
+ // ------------------------------------------------------------------
610
+ finalizeCard(source, reason) {
611
+ this.transition("completed", source, reason);
612
+ }
613
+ /**
614
+ * Close streaming mode then update card content (shared by onError and abortCard).
615
+ */
616
+ async closeStreamingAndUpdate(cardId, card, label) {
617
+ const seqBeforeClose = this.cardKit.cardKitSequence;
618
+ this.cardKit.cardKitSequence += 1;
619
+ log.info(`${label}: closing streaming mode`, {
620
+ seqBefore: seqBeforeClose,
621
+ seqAfter: this.cardKit.cardKitSequence
622
+ });
623
+ await setCardStreamingMode({
624
+ cfg: this.deps.cfg,
625
+ cardId,
626
+ streamingMode: false,
627
+ sequence: this.cardKit.cardKitSequence,
628
+ accountId: this.deps.accountId
629
+ });
630
+ const seqBeforeUpdate = this.cardKit.cardKitSequence;
631
+ this.cardKit.cardKitSequence += 1;
632
+ log.info(`${label}: updating card`, {
633
+ seqBefore: seqBeforeUpdate,
634
+ seqAfter: this.cardKit.cardKitSequence
635
+ });
636
+ await updateCardKitCard({
637
+ cfg: this.deps.cfg,
638
+ cardId,
639
+ card: toCardKit2(card),
640
+ sequence: this.cardKit.cardKitSequence,
641
+ accountId: this.deps.accountId
642
+ });
643
+ }
644
+ }
645
+ function extractApiDetail(err) {
646
+ if (!err || typeof err !== "object") return String(err);
647
+ const e = err;
648
+ return e.response?.data ? JSON.stringify(e.response.data) : String(err);
649
+ }
650
+ export {
651
+ StreamingCardController
652
+ };
653
+ //# sourceMappingURL=streaming-card-controller.js.map