botmux 2.104.0 → 2.105.0

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 (329) hide show
  1. package/README.en.md +10 -10
  2. package/README.md +10 -10
  3. package/dist/adapters/backend/sandbox.d.ts +5 -1
  4. package/dist/adapters/backend/sandbox.d.ts.map +1 -1
  5. package/dist/adapters/backend/sandbox.js +54 -5
  6. package/dist/adapters/backend/sandbox.js.map +1 -1
  7. package/dist/adapters/backend/tmux-pipe-backend.d.ts +1 -1
  8. package/dist/adapters/backend/tmux-pipe-backend.js +1 -1
  9. package/dist/adapters/backend/zellij-observe-backend.d.ts +1 -1
  10. package/dist/adapters/backend/zellij-observe-backend.js +1 -1
  11. package/dist/adapters/cli/claude-code.d.ts +1 -1
  12. package/dist/adapters/cli/relay.d.ts +2 -2
  13. package/dist/adapters/cli/relay.js +2 -2
  14. package/dist/adapters/cli/seed.d.ts +2 -2
  15. package/dist/adapters/cli/seed.js +2 -2
  16. package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
  17. package/dist/adapters/cli/shared-hints.js +1 -0
  18. package/dist/adapters/cli/shared-hints.js.map +1 -1
  19. package/dist/bot-registry.d.ts +65 -1
  20. package/dist/bot-registry.d.ts.map +1 -1
  21. package/dist/bot-registry.js +145 -0
  22. package/dist/bot-registry.js.map +1 -1
  23. package/dist/cli/send-dispatch.d.ts +44 -0
  24. package/dist/cli/send-dispatch.d.ts.map +1 -1
  25. package/dist/cli/send-dispatch.js +79 -0
  26. package/dist/cli/send-dispatch.js.map +1 -1
  27. package/dist/cli/vc-agent.d.ts +2 -0
  28. package/dist/cli/vc-agent.d.ts.map +1 -0
  29. package/dist/cli/vc-agent.js +331 -0
  30. package/dist/cli/vc-agent.js.map +1 -0
  31. package/dist/cli.d.ts.map +1 -1
  32. package/dist/cli.js +106 -24
  33. package/dist/cli.js.map +1 -1
  34. package/dist/config.d.ts +8 -0
  35. package/dist/config.d.ts.map +1 -1
  36. package/dist/config.js +13 -1
  37. package/dist/config.js.map +1 -1
  38. package/dist/core/auto-start.d.ts +2 -2
  39. package/dist/core/auto-start.js +2 -2
  40. package/dist/core/command-handler.d.ts.map +1 -1
  41. package/dist/core/command-handler.js +2 -1
  42. package/dist/core/command-handler.js.map +1 -1
  43. package/dist/core/dashboard-events.d.ts +5 -0
  44. package/dist/core/dashboard-events.d.ts.map +1 -1
  45. package/dist/core/dashboard-events.js.map +1 -1
  46. package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
  47. package/dist/core/dashboard-ipc-server.js +47 -2
  48. package/dist/core/dashboard-ipc-server.js.map +1 -1
  49. package/dist/core/idle-worker-sweeper.d.ts +1 -1
  50. package/dist/core/idle-worker-sweeper.js +1 -1
  51. package/dist/core/passthrough-commands.d.ts.map +1 -1
  52. package/dist/core/passthrough-commands.js +1 -0
  53. package/dist/core/passthrough-commands.js.map +1 -1
  54. package/dist/core/scheduler.d.ts +12 -0
  55. package/dist/core/scheduler.d.ts.map +1 -1
  56. package/dist/core/scheduler.js +67 -7
  57. package/dist/core/scheduler.js.map +1 -1
  58. package/dist/core/session-discovery.js +1 -1
  59. package/dist/core/session-discovery.js.map +1 -1
  60. package/dist/core/session-manager.d.ts.map +1 -1
  61. package/dist/core/session-manager.js +33 -7
  62. package/dist/core/session-manager.js.map +1 -1
  63. package/dist/core/trigger-session.d.ts.map +1 -1
  64. package/dist/core/trigger-session.js +78 -23
  65. package/dist/core/trigger-session.js.map +1 -1
  66. package/dist/core/worker-pool.d.ts +4 -1
  67. package/dist/core/worker-pool.d.ts.map +1 -1
  68. package/dist/core/worker-pool.js +4 -0
  69. package/dist/core/worker-pool.js.map +1 -1
  70. package/dist/core/zellij-adopt-discovery.js +1 -1
  71. package/dist/core/zellij-adopt-discovery.js.map +1 -1
  72. package/dist/daemon.d.ts +121 -0
  73. package/dist/daemon.d.ts.map +1 -1
  74. package/dist/daemon.js +2644 -2
  75. package/dist/daemon.js.map +1 -1
  76. package/dist/dashboard/federated-group-core.js +1 -1
  77. package/dist/dashboard/federated-group-core.js.map +1 -1
  78. package/dist/dashboard/federation-api.js +1 -1
  79. package/dist/dashboard/schedule-card-model.d.ts +4 -3
  80. package/dist/dashboard/schedule-card-model.d.ts.map +1 -1
  81. package/dist/dashboard/schedule-card-model.js +5 -4
  82. package/dist/dashboard/schedule-card-model.js.map +1 -1
  83. package/dist/dashboard/settings-write-applier.d.ts +37 -3
  84. package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
  85. package/dist/dashboard/settings-write-applier.js +63 -0
  86. package/dist/dashboard/settings-write-applier.js.map +1 -1
  87. package/dist/dashboard/web/i18n.d.ts.map +1 -1
  88. package/dist/dashboard/web/i18n.js +28 -0
  89. package/dist/dashboard/web/i18n.js.map +1 -1
  90. package/dist/dashboard/web/insights.js +19 -19
  91. package/dist/dashboard/web/insights.js.map +1 -1
  92. package/dist/dashboard/web/overview-page.d.ts.map +1 -1
  93. package/dist/dashboard/web/overview-page.js +7 -4
  94. package/dist/dashboard/web/overview-page.js.map +1 -1
  95. package/dist/dashboard/web/schedules-page.d.ts +1 -1
  96. package/dist/dashboard/web/schedules-page.d.ts.map +1 -1
  97. package/dist/dashboard/web/schedules-page.js +7 -3
  98. package/dist/dashboard/web/schedules-page.js.map +1 -1
  99. package/dist/dashboard/web/sessions.js +2 -2
  100. package/dist/dashboard/web/settings-page.d.ts +9 -0
  101. package/dist/dashboard/web/settings-page.d.ts.map +1 -1
  102. package/dist/dashboard/web/settings-page.js +132 -43
  103. package/dist/dashboard/web/settings-page.js.map +1 -1
  104. package/dist/dashboard/web/store.d.ts +6 -0
  105. package/dist/dashboard/web/store.d.ts.map +1 -1
  106. package/dist/dashboard/web/store.js +18 -1
  107. package/dist/dashboard/web/store.js.map +1 -1
  108. package/dist/dashboard/webhook-routes.d.ts.map +1 -1
  109. package/dist/dashboard/webhook-routes.js +24 -0
  110. package/dist/dashboard/webhook-routes.js.map +1 -1
  111. package/dist/dashboard-web/app.js +3 -3
  112. package/dist/dashboard-web/chunks/{bot-defaults-page-Z36I5CKM.js → bot-defaults-page-3OIY7N76.js} +1 -1
  113. package/dist/dashboard-web/chunks/{chunk-2BBCKWNO.js → chunk-BNEXMNQD.js} +3 -3
  114. package/dist/dashboard-web/chunks/{chunk-QDKIUULH.js → chunk-DKKOGZCG.js} +1 -1
  115. package/dist/dashboard-web/chunks/chunk-LXIK7OUJ.js +1 -0
  116. package/dist/dashboard-web/chunks/{chunk-BAMNP73K.js → chunk-VFCACTRF.js} +1 -1
  117. package/dist/dashboard-web/chunks/{connectors-I3MGERCM.js → connectors-VDOAKUW3.js} +1 -1
  118. package/dist/dashboard-web/chunks/{groups-page-DTP2L4FQ.js → groups-page-CX5AN4XG.js} +1 -1
  119. package/dist/dashboard-web/chunks/{insights-page-FNI24WYF.js → insights-page-DOMRL4S6.js} +1 -1
  120. package/dist/dashboard-web/chunks/overview-page-AZBAXVZ7.js +1 -0
  121. package/dist/dashboard-web/chunks/{roles-page-A5DZ7Q6U.js → roles-page-3FEAH6S4.js} +1 -1
  122. package/dist/dashboard-web/chunks/schedules-CTQEA7IE.js +1 -0
  123. package/dist/dashboard-web/chunks/{sessions-YJ735IH4.js → sessions-LVZCXO2Z.js} +1 -1
  124. package/dist/dashboard-web/chunks/{sessions-page-2REIJ56C.js → sessions-page-NHBJDSBC.js} +1 -1
  125. package/dist/dashboard-web/chunks/settings-page-CRDIHRNE.js +2 -0
  126. package/dist/dashboard-web/chunks/{skills-page-ZCCLHWMJ.js → skills-page-VUG3EPWX.js} +1 -1
  127. package/dist/dashboard-web/chunks/{team-federation-page-4FCGO3WW.js → team-federation-page-ZKL3YMGN.js} +1 -1
  128. package/dist/dashboard-web/chunks/{workflows-KFJ7O57L.js → workflows-4BYQQBFP.js} +1 -1
  129. package/dist/dashboard-web/index.html +1 -1
  130. package/dist/dashboard-web/style.css +111 -16
  131. package/dist/dashboard.js +196 -2
  132. package/dist/dashboard.js.map +1 -1
  133. package/dist/global-config.d.ts +30 -0
  134. package/dist/global-config.d.ts.map +1 -1
  135. package/dist/global-config.js +64 -1
  136. package/dist/global-config.js.map +1 -1
  137. package/dist/i18n/en.d.ts.map +1 -1
  138. package/dist/i18n/en.js +10 -7
  139. package/dist/i18n/en.js.map +1 -1
  140. package/dist/i18n/zh.d.ts.map +1 -1
  141. package/dist/i18n/zh.js +10 -7
  142. package/dist/i18n/zh.js.map +1 -1
  143. package/dist/im/lark/card-builder.d.ts +1 -1
  144. package/dist/im/lark/card-builder.js +1 -1
  145. package/dist/im/lark/card-handler.d.ts +3 -0
  146. package/dist/im/lark/card-handler.d.ts.map +1 -1
  147. package/dist/im/lark/card-handler.js +8 -0
  148. package/dist/im/lark/card-handler.js.map +1 -1
  149. package/dist/im/lark/client.d.ts +1 -0
  150. package/dist/im/lark/client.d.ts.map +1 -1
  151. package/dist/im/lark/client.js +19 -0
  152. package/dist/im/lark/client.js.map +1 -1
  153. package/dist/im/lark/event-dispatcher.d.ts +10 -0
  154. package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
  155. package/dist/im/lark/event-dispatcher.js +100 -21
  156. package/dist/im/lark/event-dispatcher.js.map +1 -1
  157. package/dist/im/lark/grant-command.d.ts +1 -1
  158. package/dist/im/lark/grant-command.js +1 -1
  159. package/dist/im/lark/workflow-slash-command.js +4 -0
  160. package/dist/im/lark/workflow-slash-command.js.map +1 -1
  161. package/dist/mir-prompt.d.ts +16 -0
  162. package/dist/mir-prompt.d.ts.map +1 -0
  163. package/dist/mir-prompt.js +170 -0
  164. package/dist/mir-prompt.js.map +1 -0
  165. package/dist/mir-runner.js +1 -149
  166. package/dist/mir-runner.js.map +1 -1
  167. package/dist/platform/bind.d.ts.map +1 -1
  168. package/dist/platform/bind.js +3 -11
  169. package/dist/platform/bind.js.map +1 -1
  170. package/dist/platform/binding.d.ts +4 -5
  171. package/dist/platform/binding.d.ts.map +1 -1
  172. package/dist/platform/binding.js +0 -11
  173. package/dist/platform/binding.js.map +1 -1
  174. package/dist/platform/tunnel-client.d.ts.map +1 -1
  175. package/dist/platform/tunnel-client.js +37 -28
  176. package/dist/platform/tunnel-client.js.map +1 -1
  177. package/dist/services/deployment-identity.d.ts +1 -1
  178. package/dist/services/deployment-identity.d.ts.map +1 -1
  179. package/dist/services/deployment-identity.js +1 -1
  180. package/dist/services/deployment-identity.js.map +1 -1
  181. package/dist/services/doc-subs-store.js +1 -1
  182. package/dist/services/team-board-store.js +1 -1
  183. package/dist/services/team-board-store.js.map +1 -1
  184. package/dist/services/trigger-types.d.ts +2 -1
  185. package/dist/services/trigger-types.d.ts.map +1 -1
  186. package/dist/services/trigger-types.js +11 -2
  187. package/dist/services/trigger-types.js.map +1 -1
  188. package/dist/services/vc-meeting-runtime-store.d.ts +55 -0
  189. package/dist/services/vc-meeting-runtime-store.d.ts.map +1 -0
  190. package/dist/services/vc-meeting-runtime-store.js +313 -0
  191. package/dist/services/vc-meeting-runtime-store.js.map +1 -0
  192. package/dist/services/voice/index.d.ts +6 -1
  193. package/dist/services/voice/index.d.ts.map +1 -1
  194. package/dist/services/voice/index.js +12 -5
  195. package/dist/services/voice/index.js.map +1 -1
  196. package/dist/services/voice/sami.js +1 -1
  197. package/dist/setup/lark-scopes.json +5 -0
  198. package/dist/setup/verify-permissions.d.ts +6 -0
  199. package/dist/setup/verify-permissions.d.ts.map +1 -1
  200. package/dist/setup/verify-permissions.js +17 -0
  201. package/dist/setup/verify-permissions.js.map +1 -1
  202. package/dist/skills/definitions.d.ts.map +1 -1
  203. package/dist/skills/definitions.js +10 -0
  204. package/dist/skills/definitions.js.map +1 -1
  205. package/dist/utils/daemon-discovery.d.ts +2 -0
  206. package/dist/utils/daemon-discovery.d.ts.map +1 -1
  207. package/dist/utils/daemon-discovery.js +2 -0
  208. package/dist/utils/daemon-discovery.js.map +1 -1
  209. package/dist/utils/timezone.d.ts +51 -0
  210. package/dist/utils/timezone.d.ts.map +1 -0
  211. package/dist/utils/timezone.js +110 -0
  212. package/dist/utils/timezone.js.map +1 -0
  213. package/dist/vc-agent/cards.d.ts +47 -0
  214. package/dist/vc-agent/cards.d.ts.map +1 -0
  215. package/dist/vc-agent/cards.js +489 -0
  216. package/dist/vc-agent/cards.js.map +1 -0
  217. package/dist/vc-agent/meeting-state.d.ts +39 -0
  218. package/dist/vc-agent/meeting-state.d.ts.map +1 -0
  219. package/dist/vc-agent/meeting-state.js +186 -0
  220. package/dist/vc-agent/meeting-state.js.map +1 -0
  221. package/dist/vc-agent/normalizer.d.ts +13 -0
  222. package/dist/vc-agent/normalizer.d.ts.map +1 -0
  223. package/dist/vc-agent/normalizer.js +411 -0
  224. package/dist/vc-agent/normalizer.js.map +1 -0
  225. package/dist/vc-agent/polling-source.d.ts +36 -0
  226. package/dist/vc-agent/polling-source.d.ts.map +1 -0
  227. package/dist/vc-agent/polling-source.js +129 -0
  228. package/dist/vc-agent/polling-source.js.map +1 -0
  229. package/dist/vc-agent/push-source.d.ts +13 -0
  230. package/dist/vc-agent/push-source.d.ts.map +1 -0
  231. package/dist/vc-agent/push-source.js +109 -0
  232. package/dist/vc-agent/push-source.js.map +1 -0
  233. package/dist/vc-agent/realtime/audio-source.d.ts +6 -0
  234. package/dist/vc-agent/realtime/audio-source.d.ts.map +1 -0
  235. package/dist/vc-agent/realtime/audio-source.js +17 -0
  236. package/dist/vc-agent/realtime/audio-source.js.map +1 -0
  237. package/dist/vc-agent/realtime/endpoint.d.ts +6 -0
  238. package/dist/vc-agent/realtime/endpoint.d.ts.map +1 -0
  239. package/dist/vc-agent/realtime/endpoint.js +25 -0
  240. package/dist/vc-agent/realtime/endpoint.js.map +1 -0
  241. package/dist/vc-agent/realtime/errors.d.ts +9 -0
  242. package/dist/vc-agent/realtime/errors.d.ts.map +1 -0
  243. package/dist/vc-agent/realtime/errors.js +17 -0
  244. package/dist/vc-agent/realtime/errors.js.map +1 -0
  245. package/dist/vc-agent/realtime/events.d.ts +24 -0
  246. package/dist/vc-agent/realtime/events.d.ts.map +1 -0
  247. package/dist/vc-agent/realtime/events.js +190 -0
  248. package/dist/vc-agent/realtime/events.js.map +1 -0
  249. package/dist/vc-agent/realtime/frontier.d.ts +34 -0
  250. package/dist/vc-agent/realtime/frontier.d.ts.map +1 -0
  251. package/dist/vc-agent/realtime/frontier.js +40 -0
  252. package/dist/vc-agent/realtime/frontier.js.map +1 -0
  253. package/dist/vc-agent/realtime/index.d.ts +11 -0
  254. package/dist/vc-agent/realtime/index.d.ts.map +1 -0
  255. package/dist/vc-agent/realtime/index.js +11 -0
  256. package/dist/vc-agent/realtime/index.js.map +1 -0
  257. package/dist/vc-agent/realtime/pacer.d.ts +21 -0
  258. package/dist/vc-agent/realtime/pacer.d.ts.map +1 -0
  259. package/dist/vc-agent/realtime/pacer.js +80 -0
  260. package/dist/vc-agent/realtime/pacer.js.map +1 -0
  261. package/dist/vc-agent/realtime/protobuf.d.ts +33 -0
  262. package/dist/vc-agent/realtime/protobuf.d.ts.map +1 -0
  263. package/dist/vc-agent/realtime/protobuf.js +159 -0
  264. package/dist/vc-agent/realtime/protobuf.js.map +1 -0
  265. package/dist/vc-agent/realtime/protocol.d.ts +4 -0
  266. package/dist/vc-agent/realtime/protocol.d.ts.map +1 -0
  267. package/dist/vc-agent/realtime/protocol.js +59 -0
  268. package/dist/vc-agent/realtime/protocol.js.map +1 -0
  269. package/dist/vc-agent/realtime/session.d.ts +39 -0
  270. package/dist/vc-agent/realtime/session.d.ts.map +1 -0
  271. package/dist/vc-agent/realtime/session.js +221 -0
  272. package/dist/vc-agent/realtime/session.js.map +1 -0
  273. package/dist/vc-agent/realtime/transport.d.ts +23 -0
  274. package/dist/vc-agent/realtime/transport.d.ts.map +1 -0
  275. package/dist/vc-agent/realtime/transport.js +112 -0
  276. package/dist/vc-agent/realtime/transport.js.map +1 -0
  277. package/dist/vc-agent/realtime/types.d.ts +84 -0
  278. package/dist/vc-agent/realtime/types.d.ts.map +1 -0
  279. package/dist/vc-agent/realtime/types.js +5 -0
  280. package/dist/vc-agent/realtime/types.js.map +1 -0
  281. package/dist/vc-agent/types.d.ts +142 -0
  282. package/dist/vc-agent/types.d.ts.map +1 -0
  283. package/dist/vc-agent/types.js +2 -0
  284. package/dist/vc-agent/types.js.map +1 -0
  285. package/dist/worker.js +3 -3
  286. package/dist/worker.js.map +1 -1
  287. package/dist/workflows/attempt-resume.d.ts +4 -0
  288. package/dist/workflows/attempt-resume.d.ts.map +1 -1
  289. package/dist/workflows/attempt-resume.js +2 -0
  290. package/dist/workflows/attempt-resume.js.map +1 -1
  291. package/dist/workflows/attempt-terminal.d.ts +4 -0
  292. package/dist/workflows/attempt-terminal.d.ts.map +1 -1
  293. package/dist/workflows/attempt-terminal.js.map +1 -1
  294. package/dist/workflows/daemon-spawn.d.ts.map +1 -1
  295. package/dist/workflows/daemon-spawn.js +7 -0
  296. package/dist/workflows/daemon-spawn.js.map +1 -1
  297. package/dist/workflows/events/payloads.d.ts +32 -0
  298. package/dist/workflows/events/payloads.d.ts.map +1 -1
  299. package/dist/workflows/events/payloads.js +4 -0
  300. package/dist/workflows/events/payloads.js.map +1 -1
  301. package/dist/workflows/events/schema.d.ts +56 -0
  302. package/dist/workflows/events/schema.d.ts.map +1 -1
  303. package/dist/workflows/runtime.d.ts +4 -0
  304. package/dist/workflows/runtime.d.ts.map +1 -1
  305. package/dist/workflows/runtime.js.map +1 -1
  306. package/dist/workflows/spawn-policy.d.ts +14 -0
  307. package/dist/workflows/spawn-policy.d.ts.map +1 -0
  308. package/dist/workflows/spawn-policy.js +9 -0
  309. package/dist/workflows/spawn-policy.js.map +1 -0
  310. package/dist/workflows/v3/bot-resolve.d.ts.map +1 -1
  311. package/dist/workflows/v3/bot-resolve.js +4 -0
  312. package/dist/workflows/v3/bot-resolve.js.map +1 -1
  313. package/dist/workflows/v3/cli-run.d.ts.map +1 -1
  314. package/dist/workflows/v3/cli-run.js +4 -0
  315. package/dist/workflows/v3/cli-run.js.map +1 -1
  316. package/dist/workflows/v3/contract.d.ts +9 -3
  317. package/dist/workflows/v3/contract.d.ts.map +1 -1
  318. package/dist/workflows/v3/contract.js +3 -3
  319. package/dist/workflows/v3/contract.js.map +1 -1
  320. package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -1
  321. package/dist/workflows/v3/ephemeral-pool.js +2 -0
  322. package/dist/workflows/v3/ephemeral-pool.js.map +1 -1
  323. package/dist/workflows/v3/runtime.js +1 -1
  324. package/dist/workflows/v3/runtime.js.map +1 -1
  325. package/package.json +1 -1
  326. package/dist/dashboard-web/chunks/chunk-76J7PNZI.js +0 -1
  327. package/dist/dashboard-web/chunks/overview-page-EHCZJBWY.js +0 -1
  328. package/dist/dashboard-web/chunks/schedules-RSXALJU4.js +0 -1
  329. package/dist/dashboard-web/chunks/settings-page-XKFTXTDE.js +0 -2
@@ -0,0 +1,186 @@
1
+ const DEFAULT_RECENT_LIMIT = 50_000;
2
+ const DEFAULT_TRANSCRIPT_LIMIT = 50_000;
3
+ export function createVcMeetingSessionState(input) {
4
+ return {
5
+ meeting: input.meeting,
6
+ ...(input.attentionTargetOpenId ? { attentionTargetOpenId: input.attentionTargetOpenId } : {}),
7
+ ...(input.notificationChatId ? { notificationChatId: input.notificationChatId } : {}),
8
+ ingestion: {
9
+ source: input.source ?? 'polling',
10
+ emptyPollCount: 0,
11
+ pollOrdinal: 0,
12
+ },
13
+ dedup: {
14
+ recentEventIds: [],
15
+ seenItemIds: [],
16
+ transcriptBySentenceId: {},
17
+ },
18
+ };
19
+ }
20
+ export function beginVcIngestionPass(state, now = new Date()) {
21
+ state.ingestion.pollOrdinal += 1;
22
+ state.ingestion.lastPollAt = now.toISOString();
23
+ }
24
+ export const beginVcPollingPass = beginVcIngestionPass;
25
+ function remember(values, value, limit) {
26
+ if (!value || values.includes(value))
27
+ return;
28
+ values.push(value);
29
+ if (values.length > limit)
30
+ values.splice(0, values.length - limit);
31
+ }
32
+ export function applyDropOnSeenMeetingItem(state, item, opts = {}) {
33
+ const limit = opts.recentLimit ?? DEFAULT_RECENT_LIMIT;
34
+ if (state.dedup.seenItemIds.includes(item.itemKey))
35
+ return { accepted: false };
36
+ remember(state.dedup.seenItemIds, item.itemKey, limit);
37
+ remember(state.dedup.recentEventIds, item.eventId, limit);
38
+ if (item.occurredAtMs !== undefined) {
39
+ state.ingestion.lastSeenEventTime = Math.max(state.ingestion.lastSeenEventTime ?? 0, item.occurredAtMs);
40
+ }
41
+ return { accepted: true };
42
+ }
43
+ export function upsertTranscriptMeetingItem(state, item, opts = {}) {
44
+ const nowIso = (opts.now ?? new Date()).toISOString();
45
+ const prior = state.dedup.transcriptBySentenceId[item.sentenceId];
46
+ const textChanged = !prior || prior.text !== item.text;
47
+ const finalChanged = item.isFinal === true && prior?.final !== true;
48
+ const changed = textChanged || finalChanged;
49
+ const revision = prior ? prior.revision + (changed ? 1 : 0) : 1;
50
+ const entry = {
51
+ sentenceId: item.sentenceId,
52
+ text: changed ? item.text : prior.text,
53
+ revision,
54
+ ...(item.revision !== undefined || prior?.externalRevision !== undefined ? { externalRevision: item.revision ?? prior?.externalRevision } : {}),
55
+ speaker: item.speaker.openId || item.speaker.name ? item.speaker : (prior?.speaker ?? item.speaker),
56
+ ...(item.startTimeMs !== undefined || prior?.startTimeMs !== undefined ? { startTimeMs: item.startTimeMs ?? prior?.startTimeMs } : {}),
57
+ ...(item.endTimeMs !== undefined || prior?.endTimeMs !== undefined ? { endTimeMs: item.endTimeMs ?? prior?.endTimeMs } : {}),
58
+ ...(item.language || prior?.language ? { language: item.language ?? prior?.language } : {}),
59
+ firstSeenAt: prior?.firstSeenAt ?? nowIso,
60
+ lastSeenAt: nowIso,
61
+ lastChangedAt: changed ? nowIso : prior.lastChangedAt,
62
+ firstSeenPollOrdinal: prior?.firstSeenPollOrdinal ?? state.ingestion.pollOrdinal,
63
+ lastSeenPollOrdinal: state.ingestion.pollOrdinal,
64
+ lastChangedPollOrdinal: changed ? state.ingestion.pollOrdinal : prior.lastChangedPollOrdinal,
65
+ final: item.isFinal === true || prior?.final === true,
66
+ stable: item.isFinal === true || (prior?.stable === true && !changed),
67
+ ...(prior?.flushedRevision !== undefined ? { flushedRevision: prior.flushedRevision } : {}),
68
+ };
69
+ state.dedup.transcriptBySentenceId[item.sentenceId] = entry;
70
+ pruneTranscriptEntries(state, opts.transcriptLimit ?? DEFAULT_TRANSCRIPT_LIMIT);
71
+ remember(state.dedup.seenItemIds, item.itemKey, opts.recentLimit ?? DEFAULT_RECENT_LIMIT);
72
+ remember(state.dedup.recentEventIds, item.eventId, opts.recentLimit ?? DEFAULT_RECENT_LIMIT);
73
+ if (item.occurredAtMs !== undefined) {
74
+ state.ingestion.lastSeenEventTime = Math.max(state.ingestion.lastSeenEventTime ?? 0, item.occurredAtMs);
75
+ }
76
+ return { changed, entry };
77
+ }
78
+ function pruneTranscriptEntries(state, limit) {
79
+ if (!Number.isFinite(limit) || limit <= 0)
80
+ return;
81
+ const ids = Object.keys(state.dedup.transcriptBySentenceId);
82
+ if (ids.length <= limit)
83
+ return;
84
+ ids
85
+ .map(sentenceId => ({ sentenceId, entry: state.dedup.transcriptBySentenceId[sentenceId] }))
86
+ .filter((item) => item.entry !== undefined)
87
+ .sort((a, b) => {
88
+ const aMs = Date.parse(a.entry.lastSeenAt);
89
+ const bMs = Date.parse(b.entry.lastSeenAt);
90
+ return (Number.isFinite(aMs) ? aMs : 0) - (Number.isFinite(bMs) ? bMs : 0);
91
+ })
92
+ .slice(0, ids.length - limit)
93
+ .forEach(({ sentenceId }) => {
94
+ delete state.dedup.transcriptBySentenceId[sentenceId];
95
+ });
96
+ }
97
+ export function ingestNormalizedVcMeetingItems(state, items, opts = {}) {
98
+ const acceptedItems = [];
99
+ const droppedDuplicateItems = [];
100
+ const changedTranscripts = [];
101
+ for (const item of items) {
102
+ if (item.type === 'transcript_received') {
103
+ const result = upsertTranscriptMeetingItem(state, item, opts);
104
+ if (result.changed)
105
+ changedTranscripts.push(result.entry);
106
+ continue;
107
+ }
108
+ const result = applyDropOnSeenMeetingItem(state, item, opts);
109
+ if (result.accepted)
110
+ acceptedItems.push(item);
111
+ else
112
+ droppedDuplicateItems.push(item);
113
+ }
114
+ const anyChange = acceptedItems.length > 0 || changedTranscripts.length > 0;
115
+ state.ingestion.emptyPollCount = anyChange ? 0 : state.ingestion.emptyPollCount + 1;
116
+ return { acceptedItems, droppedDuplicateItems, changedTranscripts };
117
+ }
118
+ export function collectStableTranscriptItems(state, opts = {}) {
119
+ const windows = opts.stabilizePollWindows ?? 1;
120
+ const nowMs = (opts.now ?? new Date()).getTime();
121
+ const ready = [];
122
+ for (const entry of Object.values(state.dedup.transcriptBySentenceId)) {
123
+ const lastChangedMs = Date.parse(entry.lastChangedAt);
124
+ const stableByTime = opts.stabilizeMs !== undefined
125
+ && Number.isFinite(lastChangedMs)
126
+ && nowMs - lastChangedMs >= opts.stabilizeMs;
127
+ const stableByWindow = state.ingestion.pollOrdinal - entry.lastChangedPollOrdinal >= windows;
128
+ const stable = entry.final || stableByTime || (opts.stabilizeMs === undefined && stableByWindow);
129
+ entry.stable = stable;
130
+ if (!stable || entry.flushedRevision === entry.revision)
131
+ continue;
132
+ if (opts.markFlushed !== false)
133
+ entry.flushedRevision = entry.revision;
134
+ ready.push({
135
+ source: state.ingestion.source,
136
+ type: 'transcript_received',
137
+ meetingId: state.meeting.id,
138
+ itemKey: `transcript:${entry.sentenceId}`,
139
+ sentenceId: entry.sentenceId,
140
+ speaker: entry.speaker,
141
+ ...(entry.startTimeMs !== undefined ? { startTimeMs: entry.startTimeMs } : {}),
142
+ ...(entry.endTimeMs !== undefined ? { endTimeMs: entry.endTimeMs } : {}),
143
+ ...(entry.language ? { language: entry.language } : {}),
144
+ text: entry.text,
145
+ revision: entry.revision,
146
+ isFinal: entry.final,
147
+ });
148
+ }
149
+ return ready;
150
+ }
151
+ export function markVcTranscriptItemsFlushed(state, items) {
152
+ for (const item of items) {
153
+ const entry = state.dedup.transcriptBySentenceId[item.sentenceId];
154
+ if (!entry)
155
+ continue;
156
+ if (item.revision !== undefined && item.revision === entry.revision) {
157
+ entry.flushedRevision = entry.revision;
158
+ }
159
+ }
160
+ }
161
+ export function buildVcMeetingStatePayload(state, items, page = {}) {
162
+ const transcripts = Object.values(state.dedup.transcriptBySentenceId);
163
+ return {
164
+ format: 'botmux.vc-meeting.v1',
165
+ source: state.ingestion.source === 'push' ? 'lark:vc.bot.meeting_activity_v1' : 'lark-cli:vc:+meeting-events',
166
+ meeting: state.meeting,
167
+ session: {
168
+ ...(state.attentionTargetOpenId ? { attentionTargetOpenId: state.attentionTargetOpenId } : {}),
169
+ ...(state.notificationChatId ? { notificationChatId: state.notificationChatId } : {}),
170
+ },
171
+ poll: {
172
+ ordinal: state.ingestion.pollOrdinal,
173
+ ...(page.pageToken ?? state.ingestion.pageToken ? { pageToken: page.pageToken ?? state.ingestion.pageToken } : {}),
174
+ ...(page.hasMore !== undefined ? { hasMore: page.hasMore } : {}),
175
+ ...(state.ingestion.lastPollAt ? { lastPollAt: state.ingestion.lastPollAt } : {}),
176
+ emptyPollCount: state.ingestion.emptyPollCount,
177
+ },
178
+ items,
179
+ state: {
180
+ transcriptCount: transcripts.length,
181
+ stableTranscriptCount: transcripts.filter((t) => t.stable).length,
182
+ seenItemCount: state.dedup.seenItemIds.length,
183
+ },
184
+ };
185
+ }
186
+ //# sourceMappingURL=meeting-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meeting-state.js","sourceRoot":"","sources":["../../src/vc-agent/meeting-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { NormalizedVcMeetingBatch, VcMeetingActivityType, VcMeetingSource } from './types.js';
2
+ declare function parseTimeMs(...values: unknown[]): number | undefined;
3
+ declare function eventTypeOf(rawEvent: unknown): VcMeetingActivityType | undefined;
4
+ export declare function normalizeVcMeetingEvents(raw: unknown, opts?: {
5
+ meetingId?: string;
6
+ source?: VcMeetingSource;
7
+ }): NormalizedVcMeetingBatch;
8
+ export declare const _testOnly: {
9
+ parseTimeMs: typeof parseTimeMs;
10
+ eventTypeOf: typeof eventTypeOf;
11
+ };
12
+ export {};
13
+ //# sourceMappingURL=normalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../../src/vc-agent/normalizer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,wBAAwB,EAIxB,qBAAqB,EAGrB,eAAe,EAChB,MAAM,YAAY,CAAC;AAwCpB,iBAAS,WAAW,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,GAAG,SAAS,CAe7D;AA4GD,iBAAS,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,qBAAqB,GAAG,SAAS,CAiBzE;AAoeD,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,OAAO,EACZ,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,eAAe,CAAA;CAAO,GAC1D,wBAAwB,CAyB1B;AAED,eAAO,MAAM,SAAS;;;CAGrB,CAAC"}
@@ -0,0 +1,411 @@
1
+ import { createHash } from 'node:crypto';
2
+ const ACTIVITY_TYPES = [
3
+ 'participant_joined',
4
+ 'participant_left',
5
+ 'chat_received',
6
+ 'transcript_received',
7
+ 'magic_share_started',
8
+ 'magic_share_ended',
9
+ ];
10
+ function isRecord(v) {
11
+ return !!v && typeof v === 'object' && !Array.isArray(v);
12
+ }
13
+ function getPath(obj, path) {
14
+ let cur = obj;
15
+ for (const part of path.split('.')) {
16
+ if (!isRecord(cur))
17
+ return undefined;
18
+ cur = cur[part];
19
+ }
20
+ return cur;
21
+ }
22
+ function firstString(...values) {
23
+ for (const v of values) {
24
+ if (typeof v === 'string' && v.trim())
25
+ return v.trim();
26
+ if (typeof v === 'number' && Number.isFinite(v))
27
+ return String(v);
28
+ }
29
+ return undefined;
30
+ }
31
+ function firstNumber(...values) {
32
+ for (const v of values) {
33
+ if (typeof v === 'number' && Number.isFinite(v))
34
+ return v;
35
+ if (typeof v === 'string' && v.trim() && Number.isFinite(Number(v)))
36
+ return Number(v);
37
+ }
38
+ return undefined;
39
+ }
40
+ function parseTimeMs(...values) {
41
+ for (const v of values) {
42
+ if (typeof v === 'number' && Number.isFinite(v)) {
43
+ return v < 10_000_000_000 ? Math.floor(v * 1000) : Math.floor(v);
44
+ }
45
+ if (typeof v === 'string' && v.trim()) {
46
+ if (/^\d+$/.test(v.trim())) {
47
+ const n = Number(v.trim());
48
+ if (Number.isFinite(n))
49
+ return n < 10_000_000_000 ? Math.floor(n * 1000) : Math.floor(n);
50
+ }
51
+ const parsed = Date.parse(v);
52
+ if (Number.isFinite(parsed))
53
+ return parsed;
54
+ }
55
+ }
56
+ return undefined;
57
+ }
58
+ function shortHash(input) {
59
+ return createHash('sha256').update(input).digest('hex').slice(0, 16);
60
+ }
61
+ function actorFrom(...records) {
62
+ const openId = firstString(...records.flatMap((r) => [
63
+ getPath(r, 'open_id'),
64
+ getPath(r, 'openId'),
65
+ getPath(r, 'user_id'),
66
+ getPath(r, 'userId'),
67
+ getPath(r, 'id'),
68
+ getPath(r, 'user.open_id'),
69
+ getPath(r, 'user.openId'),
70
+ getPath(r, 'user.user_id'),
71
+ getPath(r, 'user.userId'),
72
+ getPath(r, 'participant.open_id'),
73
+ getPath(r, 'participant.openId'),
74
+ getPath(r, 'participant.user_id'),
75
+ getPath(r, 'participant.userId'),
76
+ getPath(r, 'sender.open_id'),
77
+ getPath(r, 'sender.openId'),
78
+ getPath(r, 'sender.user_id'),
79
+ getPath(r, 'sender.userId'),
80
+ getPath(r, 'sender.id'),
81
+ getPath(r, 'operator.open_id'),
82
+ getPath(r, 'operator.openId'),
83
+ getPath(r, 'operator.user_id'),
84
+ getPath(r, 'operator.userId'),
85
+ getPath(r, 'operator.id'),
86
+ getPath(r, 'from.open_id'),
87
+ getPath(r, 'from.openId'),
88
+ getPath(r, 'from.user_id'),
89
+ getPath(r, 'from.userId'),
90
+ getPath(r, 'from.id'),
91
+ getPath(r, 'message.sender.open_id'),
92
+ getPath(r, 'message.sender.openId'),
93
+ getPath(r, 'message.sender.user_id'),
94
+ getPath(r, 'message.sender.userId'),
95
+ getPath(r, 'message.sender.id'),
96
+ ]));
97
+ const name = firstString(...records.flatMap((r) => [
98
+ getPath(r, 'name'),
99
+ getPath(r, 'user_name'),
100
+ getPath(r, 'userName'),
101
+ getPath(r, 'display_name'),
102
+ getPath(r, 'displayName'),
103
+ getPath(r, 'user.name'),
104
+ getPath(r, 'user.user_name'),
105
+ getPath(r, 'user.userName'),
106
+ getPath(r, 'user.display_name'),
107
+ getPath(r, 'user.displayName'),
108
+ getPath(r, 'participant.name'),
109
+ getPath(r, 'participant.user_name'),
110
+ getPath(r, 'participant.userName'),
111
+ getPath(r, 'participant.display_name'),
112
+ getPath(r, 'participant.displayName'),
113
+ getPath(r, 'sender.name'),
114
+ getPath(r, 'sender.user_name'),
115
+ getPath(r, 'sender.userName'),
116
+ getPath(r, 'sender.display_name'),
117
+ getPath(r, 'sender.displayName'),
118
+ getPath(r, 'operator.name'),
119
+ getPath(r, 'operator.user_name'),
120
+ getPath(r, 'operator.userName'),
121
+ getPath(r, 'operator.display_name'),
122
+ getPath(r, 'operator.displayName'),
123
+ getPath(r, 'from.name'),
124
+ getPath(r, 'from.user_name'),
125
+ getPath(r, 'from.userName'),
126
+ getPath(r, 'from.display_name'),
127
+ getPath(r, 'from.displayName'),
128
+ getPath(r, 'message.sender.name'),
129
+ getPath(r, 'message.sender.user_name'),
130
+ getPath(r, 'message.sender.userName'),
131
+ getPath(r, 'message.sender.display_name'),
132
+ getPath(r, 'message.sender.displayName'),
133
+ ]));
134
+ const userType = firstNumber(...records.flatMap((r) => [
135
+ getPath(r, 'user_type'),
136
+ getPath(r, 'userType'),
137
+ getPath(r, 'participant.user_type'),
138
+ getPath(r, 'participant.userType'),
139
+ getPath(r, 'user.user_type'),
140
+ getPath(r, 'user.userType'),
141
+ getPath(r, 'sender.user_type'),
142
+ getPath(r, 'sender.userType'),
143
+ getPath(r, 'operator.user_type'),
144
+ getPath(r, 'operator.userType'),
145
+ getPath(r, 'from.user_type'),
146
+ getPath(r, 'from.userType'),
147
+ getPath(r, 'message.sender.user_type'),
148
+ getPath(r, 'message.sender.userType'),
149
+ ]));
150
+ return {
151
+ ...(openId ? { openId } : {}),
152
+ ...(name ? { name } : {}),
153
+ ...(userType !== undefined ? { userType } : {}),
154
+ };
155
+ }
156
+ function eventTypeOf(rawEvent) {
157
+ const direct = firstString(getPath(rawEvent, 'event_type'), getPath(rawEvent, 'eventType'), getPath(rawEvent, 'activity_event_type'), getPath(rawEvent, 'activityEventType'), getPath(rawEvent, 'type'));
158
+ if (direct && ACTIVITY_TYPES.includes(direct)) {
159
+ return direct;
160
+ }
161
+ if (isRecord(rawEvent)) {
162
+ for (const t of ACTIVITY_TYPES) {
163
+ if (rawEvent[t] !== undefined || rawEvent[`${t}_items`] !== undefined)
164
+ return t;
165
+ }
166
+ }
167
+ return undefined;
168
+ }
169
+ function firstArray(...values) {
170
+ for (const v of values) {
171
+ if (Array.isArray(v))
172
+ return v;
173
+ }
174
+ return undefined;
175
+ }
176
+ function asArray(v) {
177
+ if (Array.isArray(v))
178
+ return v;
179
+ return v === undefined || v === null ? [] : [v];
180
+ }
181
+ function payloadsForType(rawEvent, type) {
182
+ const candidates = [
183
+ getPath(rawEvent, `${type}_items`),
184
+ getPath(rawEvent, type),
185
+ getPath(rawEvent, `payload.${type}_items`),
186
+ getPath(rawEvent, `payload.${type}`),
187
+ getPath(rawEvent, `data.${type}_items`),
188
+ getPath(rawEvent, `data.${type}`),
189
+ getPath(rawEvent, 'items'),
190
+ getPath(rawEvent, 'payload.items'),
191
+ getPath(rawEvent, 'data.items'),
192
+ ];
193
+ for (const c of candidates) {
194
+ const values = asArray(c);
195
+ if (values.length > 0)
196
+ return values;
197
+ }
198
+ return [rawEvent];
199
+ }
200
+ function rawEventsFrom(raw) {
201
+ if (Array.isArray(raw))
202
+ return raw;
203
+ const activityItems = firstArray(
204
+ // Official VC bot activity push field. The misspelling is part of the
205
+ // upstream schema and must be consumed verbatim.
206
+ getPath(raw, 'meeting_actitivty_items'), getPath(raw, 'event.meeting_actitivty_items'), getPath(raw, 'data.event.meeting_actitivty_items'), getPath(raw, 'payload.event.meeting_actitivty_items'),
207
+ // Accept the correctly-spelled form defensively for CLI fixtures / future schema fixes.
208
+ getPath(raw, 'meeting_activity_items'), getPath(raw, 'event.meeting_activity_items'), getPath(raw, 'data.event.meeting_activity_items'), getPath(raw, 'payload.event.meeting_activity_items'));
209
+ if (activityItems)
210
+ return activityItems;
211
+ const candidates = [
212
+ getPath(raw, 'events'),
213
+ getPath(raw, 'data.events'),
214
+ getPath(raw, 'data.items'),
215
+ getPath(raw, 'items'),
216
+ ];
217
+ for (const c of candidates) {
218
+ if (Array.isArray(c))
219
+ return c;
220
+ }
221
+ const directCandidates = [
222
+ getPath(raw, 'event'),
223
+ getPath(raw, 'data.event'),
224
+ getPath(raw, 'payload.event'),
225
+ raw,
226
+ ];
227
+ for (const c of directCandidates) {
228
+ if (isRecord(c) && eventTypeOf(c))
229
+ return [c];
230
+ }
231
+ return [];
232
+ }
233
+ function meetingRefFrom(raw, fallbackMeetingId) {
234
+ const eventMeeting = rawEventsFrom(raw).map((e) => getPath(e, 'meeting')).find(isRecord);
235
+ const meeting = getPath(raw, 'meeting')
236
+ ?? getPath(raw, 'event.meeting')
237
+ ?? getPath(raw, 'data.meeting')
238
+ ?? getPath(raw, 'data.event.meeting')
239
+ ?? eventMeeting
240
+ ?? raw;
241
+ const id = firstString(fallbackMeetingId, getPath(meeting, 'id'), getPath(meeting, 'meeting_id'), getPath(raw, 'meeting_id'), getPath(raw, 'event.meeting_id'), getPath(raw, 'data.meeting_id'), getPath(raw, 'data.event.meeting_id'));
242
+ const meetingNo = firstString(getPath(meeting, 'meeting_no'), getPath(meeting, 'meetingNo'), getPath(raw, 'meeting_no'), getPath(raw, 'meetingNo'), getPath(raw, 'event.meeting_no'), getPath(raw, 'event.meetingNo'), getPath(raw, 'data.event.meeting_no'), getPath(raw, 'data.event.meetingNo'));
243
+ const topic = firstString(getPath(meeting, 'topic'), getPath(meeting, 'title'), getPath(meeting, 'meeting_title'), getPath(raw, 'topic'), getPath(raw, 'title'), getPath(raw, 'meeting_title'), getPath(raw, 'event.topic'), getPath(raw, 'event.title'), getPath(raw, 'event.meeting_title'));
244
+ const startTimeMs = parseTimeMs(getPath(meeting, 'start_time'), getPath(meeting, 'startTime'), getPath(meeting, 'start_time_ms'), getPath(meeting, 'startTimeMs'), getPath(raw, 'start_time'), getPath(raw, 'startTime'), getPath(raw, 'start_time_ms'), getPath(raw, 'startTimeMs'), getPath(raw, 'event.start_time'), getPath(raw, 'event.startTime'), getPath(raw, 'event.start_time_ms'), getPath(raw, 'event.startTimeMs'));
245
+ const host = actorFrom(getPath(meeting, 'host_user'), getPath(meeting, 'hostUser'), getPath(meeting, 'host'), {
246
+ open_id: getPath(meeting, 'host_open_id'),
247
+ user_id: getPath(meeting, 'host_user_id'),
248
+ name: getPath(meeting, 'host_name'),
249
+ user_type: getPath(meeting, 'host_user_type'),
250
+ }, getPath(raw, 'host_user'), getPath(raw, 'hostUser'), getPath(raw, 'host'), getPath(raw, 'event.host_user'), getPath(raw, 'event.hostUser'), getPath(raw, 'event.host'));
251
+ return {
252
+ id: id ?? '',
253
+ ...(meetingNo ? { meetingNo } : {}),
254
+ ...(topic ? { topic } : {}),
255
+ ...(startTimeMs !== undefined ? { startTimeMs } : {}),
256
+ ...(host.openId ? { hostOpenId: host.openId } : {}),
257
+ ...(host.name ? { hostName: host.name } : {}),
258
+ };
259
+ }
260
+ function eventIdOf(rawEvent) {
261
+ return firstString(getPath(rawEvent, 'event_id'), getPath(rawEvent, 'eventId'), getPath(rawEvent, 'id'), getPath(rawEvent, 'header.event_id'));
262
+ }
263
+ function occurredAt(rawEvent, item) {
264
+ return parseTimeMs(getPath(item, 'time'), getPath(item, 'timestamp'), getPath(item, 'event_time'), getPath(item, 'eventTime'), getPath(item, 'create_time'), getPath(item, 'createTime'), getPath(item, 'send_time'), getPath(item, 'sendTime'), getPath(item, 'send_time_ms'), getPath(item, 'sendTimeMs'), getPath(item, 'join_time'), getPath(item, 'joinTime'), getPath(item, 'join_time_ms'), getPath(item, 'joinTimeMs'), getPath(item, 'leave_time'), getPath(item, 'leaveTime'), getPath(item, 'leave_time_ms'), getPath(item, 'leaveTimeMs'), getPath(item, 'start_time'), getPath(item, 'startTime'), getPath(item, 'start_time_ms'), getPath(item, 'startTimeMs'), getPath(item, 'end_time'), getPath(item, 'endTime'), getPath(item, 'end_time_ms'), getPath(item, 'endTimeMs'), getPath(rawEvent, 'event_time'), getPath(rawEvent, 'eventTime'), getPath(rawEvent, 'time'), getPath(rawEvent, 'timestamp'), getPath(rawEvent, 'create_time'), getPath(rawEvent, 'createTime'), getPath(rawEvent, 'send_time'), getPath(rawEvent, 'sendTime'), getPath(rawEvent, 'send_time_ms'), getPath(rawEvent, 'sendTimeMs'), getPath(rawEvent, 'join_time'), getPath(rawEvent, 'joinTime'), getPath(rawEvent, 'join_time_ms'), getPath(rawEvent, 'joinTimeMs'), getPath(rawEvent, 'leave_time'), getPath(rawEvent, 'leaveTime'), getPath(rawEvent, 'leave_time_ms'), getPath(rawEvent, 'leaveTimeMs'));
265
+ }
266
+ function normalizeParticipant(source, meetingId, type, rawEvent, item) {
267
+ const participant = actorFrom(item, getPath(item, 'participant'), getPath(item, 'user'), getPath(item, 'operator'), getPath(item, 'from'), rawEvent, getPath(rawEvent, 'participant'), getPath(rawEvent, 'user'), getPath(rawEvent, 'operator'), getPath(rawEvent, 'from'));
268
+ const occurredAtMs = occurredAt(rawEvent, item);
269
+ const itemKey = [
270
+ type,
271
+ participant.openId ?? participant.name ?? 'unknown',
272
+ occurredAtMs ?? eventIdOf(rawEvent) ?? '',
273
+ ].join(':');
274
+ return {
275
+ source,
276
+ type,
277
+ meetingId,
278
+ ...(eventIdOf(rawEvent) ? { eventId: eventIdOf(rawEvent) } : {}),
279
+ itemKey,
280
+ ...(occurredAtMs !== undefined ? { occurredAtMs } : {}),
281
+ participant,
282
+ ...(firstString(getPath(item, 'role'), getPath(item, 'participant.role'), getPath(rawEvent, 'role'), getPath(rawEvent, 'participant.role')) ? {
283
+ role: firstString(getPath(item, 'role'), getPath(item, 'participant.role'), getPath(rawEvent, 'role'), getPath(rawEvent, 'participant.role')),
284
+ } : {}),
285
+ };
286
+ }
287
+ function normalizeChat(source, meetingId, rawEvent, item) {
288
+ const sender = actorFrom(item, getPath(item, 'sender'), getPath(item, 'user'), getPath(item, 'operator'), getPath(item, 'from'), getPath(item, 'message.sender'), rawEvent, getPath(rawEvent, 'sender'), getPath(rawEvent, 'user'), getPath(rawEvent, 'operator'), getPath(rawEvent, 'from'));
289
+ const messageId = firstString(getPath(item, 'message_id'), getPath(item, 'messageId'), getPath(item, 'id'), getPath(item, 'message.message_id'), getPath(item, 'message.messageId'), getPath(item, 'message.id'), getPath(rawEvent, 'message_id'), getPath(rawEvent, 'messageId'), getPath(rawEvent, 'message.message_id'), getPath(rawEvent, 'message.messageId'), getPath(rawEvent, 'message.id'));
290
+ const text = firstString(getPath(item, 'text'), getPath(item, 'content.text'), getPath(item, 'content.plain_text'), getPath(item, 'content.plainText'), getPath(item, 'content.value'), getPath(item, 'message.text'), getPath(item, 'message.content.text'), getPath(item, 'message.content.plain_text'), getPath(item, 'message.content.plainText'), getPath(item, 'message.content.value'), getPath(item, 'message.message_content'), getPath(item, 'message.messageContent'), getPath(item, 'message_content'), getPath(item, 'messageContent'), getPath(item, 'body.text'), getPath(item, 'body.content.text'), typeof getPath(item, 'content') === 'string' ? getPath(item, 'content') : undefined, typeof getPath(item, 'message.content') === 'string' ? getPath(item, 'message.content') : undefined);
291
+ const occurredAtMs = occurredAt(rawEvent, item);
292
+ return {
293
+ source,
294
+ type: 'chat_received',
295
+ meetingId,
296
+ ...(eventIdOf(rawEvent) ? { eventId: eventIdOf(rawEvent) } : {}),
297
+ itemKey: `chat:${messageId ?? shortHash(`${sender.openId ?? sender.name ?? ''}:${occurredAtMs ?? ''}:${text ?? ''}`)}`,
298
+ ...(occurredAtMs !== undefined ? { occurredAtMs } : {}),
299
+ ...(messageId ? { messageId } : {}),
300
+ sender,
301
+ ...(firstString(getPath(item, 'message_type'), getPath(item, 'messageType'), getPath(item, 'type'), getPath(item, 'message.message_type'), getPath(item, 'message.messageType'), getPath(rawEvent, 'message_type'), getPath(rawEvent, 'messageType')) ? {
302
+ messageType: firstString(getPath(item, 'message_type'), getPath(item, 'messageType'), getPath(item, 'type'), getPath(item, 'message.message_type'), getPath(item, 'message.messageType'), getPath(rawEvent, 'message_type'), getPath(rawEvent, 'messageType')),
303
+ } : {}),
304
+ ...(text ? { text } : {}),
305
+ };
306
+ }
307
+ function normalizeTranscript(source, meetingId, rawEvent, item) {
308
+ const speaker = actorFrom(item, getPath(item, 'speaker'), getPath(item, 'user'), getPath(item, 'operator'), rawEvent, getPath(rawEvent, 'speaker'), getPath(rawEvent, 'user'), getPath(rawEvent, 'operator'));
309
+ const text = firstString(getPath(item, 'text'), getPath(item, 'content.text'), getPath(item, 'content.plain_text'), getPath(item, 'content.plainText'), getPath(item, 'content'), getPath(item, 'sentence.text'), getPath(item, 'sentence.content'), getPath(item, 'sentence'), getPath(item, 'transcript.text'), getPath(item, 'transcript.content'), getPath(item, 'transcript')) ?? '';
310
+ const startTimeMs = parseTimeMs(getPath(item, 'start_time'), getPath(item, 'startTime'), getPath(item, 'start_time_ms'), getPath(item, 'startTimeMs'));
311
+ const endTimeMs = parseTimeMs(getPath(item, 'end_time'), getPath(item, 'endTime'), getPath(item, 'end_time_ms'), getPath(item, 'endTimeMs'));
312
+ const sentenceId = firstString(getPath(item, 'sentence_id'), getPath(item, 'sentenceId'), getPath(item, 'id'), getPath(item, 'sentence.sentence_id'), getPath(item, 'sentence.sentenceId'), getPath(item, 'sentence.id'), getPath(item, 'transcript.sentence_id'), getPath(item, 'transcript.sentenceId'), getPath(item, 'transcript.id')) ?? `fallback:${shortHash(`${speaker.openId ?? speaker.name ?? ''}:${startTimeMs ?? ''}:${endTimeMs ?? ''}:${text}`)}`;
313
+ const isFinalRaw = getPath(item, 'is_final') ?? getPath(item, 'isFinal') ?? getPath(item, 'final');
314
+ const status = firstString(getPath(item, 'status'), getPath(item, 'state'));
315
+ const occurredAtMs = endTimeMs ?? startTimeMs ?? occurredAt(rawEvent, item);
316
+ return {
317
+ source,
318
+ type: 'transcript_received',
319
+ meetingId,
320
+ ...(eventIdOf(rawEvent) ? { eventId: eventIdOf(rawEvent) } : {}),
321
+ itemKey: `transcript:${sentenceId}`,
322
+ ...(occurredAtMs !== undefined ? { occurredAtMs } : {}),
323
+ sentenceId,
324
+ speaker,
325
+ ...(startTimeMs !== undefined ? { startTimeMs } : {}),
326
+ ...(endTimeMs !== undefined ? { endTimeMs } : {}),
327
+ ...(firstString(getPath(item, 'language'), getPath(item, 'lang'), getPath(item, 'sentence.language'), getPath(item, 'transcript.language')) ? {
328
+ language: firstString(getPath(item, 'language'), getPath(item, 'lang'), getPath(item, 'sentence.language'), getPath(item, 'transcript.language')),
329
+ } : {}),
330
+ text,
331
+ ...(firstNumber(getPath(item, 'revision'), getPath(item, 'version'), getPath(item, 'rev')) !== undefined ? {
332
+ revision: firstNumber(getPath(item, 'revision'), getPath(item, 'version'), getPath(item, 'rev')),
333
+ } : {}),
334
+ ...(typeof isFinalRaw === 'boolean' || status ? {
335
+ isFinal: isFinalRaw === true || status === 'final' || status === 'stable',
336
+ } : {}),
337
+ };
338
+ }
339
+ function normalizeMagicShare(source, meetingId, type, rawEvent, item) {
340
+ const shareDoc = getPath(item, 'share_doc')
341
+ ?? getPath(item, 'shareDoc')
342
+ ?? getPath(item, 'document')
343
+ ?? getPath(item, 'doc')
344
+ ?? getPath(rawEvent, 'share_doc')
345
+ ?? getPath(rawEvent, 'shareDoc')
346
+ ?? getPath(rawEvent, 'document')
347
+ ?? getPath(rawEvent, 'doc')
348
+ ?? item;
349
+ const shareId = firstString(getPath(item, 'share_id'), getPath(item, 'shareId'), getPath(rawEvent, 'share_id'), getPath(rawEvent, 'shareId'), getPath(shareDoc, 'token'), getPath(shareDoc, 'id'));
350
+ const occurredAtMs = occurredAt(rawEvent, item);
351
+ return {
352
+ source,
353
+ type,
354
+ meetingId,
355
+ ...(eventIdOf(rawEvent) ? { eventId: eventIdOf(rawEvent) } : {}),
356
+ itemKey: `${type}:${shareId ?? shortHash(`${firstString(getPath(shareDoc, 'title')) ?? ''}:${occurredAtMs ?? ''}`)}`,
357
+ ...(occurredAtMs !== undefined ? { occurredAtMs } : {}),
358
+ ...(shareId ? { shareId } : {}),
359
+ ...(firstString(getPath(shareDoc, 'title'), getPath(item, 'title'), getPath(rawEvent, 'title')) ? {
360
+ title: firstString(getPath(shareDoc, 'title'), getPath(item, 'title'), getPath(rawEvent, 'title')),
361
+ } : {}),
362
+ ...(firstString(getPath(shareDoc, 'url'), getPath(item, 'url'), getPath(rawEvent, 'url')) ? {
363
+ url: firstString(getPath(shareDoc, 'url'), getPath(item, 'url'), getPath(rawEvent, 'url')),
364
+ } : {}),
365
+ operator: actorFrom(item, getPath(item, 'operator'), getPath(item, 'user'), getPath(item, 'from'), rawEvent, getPath(rawEvent, 'operator'), getPath(rawEvent, 'user'), getPath(rawEvent, 'from')),
366
+ };
367
+ }
368
+ function normalizeItem(source, meetingId, type, rawEvent, item) {
369
+ switch (type) {
370
+ case 'participant_joined':
371
+ case 'participant_left':
372
+ return normalizeParticipant(source, meetingId, type, rawEvent, item);
373
+ case 'chat_received':
374
+ return normalizeChat(source, meetingId, rawEvent, item);
375
+ case 'transcript_received':
376
+ return normalizeTranscript(source, meetingId, rawEvent, item);
377
+ case 'magic_share_started':
378
+ case 'magic_share_ended':
379
+ return normalizeMagicShare(source, meetingId, type, rawEvent, item);
380
+ }
381
+ }
382
+ export function normalizeVcMeetingEvents(raw, opts = {}) {
383
+ const source = opts.source ?? 'polling';
384
+ const meeting = meetingRefFrom(raw, opts.meetingId);
385
+ const meetingId = meeting.id || opts.meetingId || '';
386
+ const items = [];
387
+ for (const rawEvent of rawEventsFrom(raw)) {
388
+ const type = eventTypeOf(rawEvent);
389
+ if (!type)
390
+ continue;
391
+ for (const payload of payloadsForType(rawEvent, type)) {
392
+ items.push(normalizeItem(source, meetingId, type, rawEvent, payload));
393
+ }
394
+ }
395
+ return {
396
+ source,
397
+ meeting: { ...meeting, id: meetingId },
398
+ items,
399
+ ...(firstString(getPath(raw, 'page_token'), getPath(raw, 'data.page_token')) ? {
400
+ pageToken: firstString(getPath(raw, 'page_token'), getPath(raw, 'data.page_token')),
401
+ } : {}),
402
+ ...(typeof (getPath(raw, 'has_more') ?? getPath(raw, 'data.has_more')) === 'boolean' ? {
403
+ hasMore: (getPath(raw, 'has_more') ?? getPath(raw, 'data.has_more')),
404
+ } : {}),
405
+ };
406
+ }
407
+ export const _testOnly = {
408
+ parseTimeMs,
409
+ eventTypeOf,
410
+ };
411
+ //# sourceMappingURL=normalizer.js.map