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.
- package/README.en.md +10 -10
- package/README.md +10 -10
- package/dist/adapters/backend/sandbox.d.ts +5 -1
- package/dist/adapters/backend/sandbox.d.ts.map +1 -1
- package/dist/adapters/backend/sandbox.js +54 -5
- package/dist/adapters/backend/sandbox.js.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.d.ts +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.js +1 -1
- package/dist/adapters/backend/zellij-observe-backend.d.ts +1 -1
- package/dist/adapters/backend/zellij-observe-backend.js +1 -1
- package/dist/adapters/cli/claude-code.d.ts +1 -1
- package/dist/adapters/cli/relay.d.ts +2 -2
- package/dist/adapters/cli/relay.js +2 -2
- package/dist/adapters/cli/seed.d.ts +2 -2
- package/dist/adapters/cli/seed.js +2 -2
- package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
- package/dist/adapters/cli/shared-hints.js +1 -0
- package/dist/adapters/cli/shared-hints.js.map +1 -1
- package/dist/bot-registry.d.ts +65 -1
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +145 -0
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/send-dispatch.d.ts +44 -0
- package/dist/cli/send-dispatch.d.ts.map +1 -1
- package/dist/cli/send-dispatch.js +79 -0
- package/dist/cli/send-dispatch.js.map +1 -1
- package/dist/cli/vc-agent.d.ts +2 -0
- package/dist/cli/vc-agent.d.ts.map +1 -0
- package/dist/cli/vc-agent.js +331 -0
- package/dist/cli/vc-agent.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +106 -24
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -1
- package/dist/config.js.map +1 -1
- package/dist/core/auto-start.d.ts +2 -2
- package/dist/core/auto-start.js +2 -2
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +2 -1
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-events.d.ts +5 -0
- package/dist/core/dashboard-events.d.ts.map +1 -1
- package/dist/core/dashboard-events.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +47 -2
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/idle-worker-sweeper.d.ts +1 -1
- package/dist/core/idle-worker-sweeper.js +1 -1
- package/dist/core/passthrough-commands.d.ts.map +1 -1
- package/dist/core/passthrough-commands.js +1 -0
- package/dist/core/passthrough-commands.js.map +1 -1
- package/dist/core/scheduler.d.ts +12 -0
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +67 -7
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/session-discovery.js +1 -1
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +33 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/trigger-session.d.ts.map +1 -1
- package/dist/core/trigger-session.js +78 -23
- package/dist/core/trigger-session.js.map +1 -1
- package/dist/core/worker-pool.d.ts +4 -1
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +4 -0
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/core/zellij-adopt-discovery.js +1 -1
- package/dist/core/zellij-adopt-discovery.js.map +1 -1
- package/dist/daemon.d.ts +121 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +2644 -2
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/federated-group-core.js +1 -1
- package/dist/dashboard/federated-group-core.js.map +1 -1
- package/dist/dashboard/federation-api.js +1 -1
- package/dist/dashboard/schedule-card-model.d.ts +4 -3
- package/dist/dashboard/schedule-card-model.d.ts.map +1 -1
- package/dist/dashboard/schedule-card-model.js +5 -4
- package/dist/dashboard/schedule-card-model.js.map +1 -1
- package/dist/dashboard/settings-write-applier.d.ts +37 -3
- package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
- package/dist/dashboard/settings-write-applier.js +63 -0
- package/dist/dashboard/settings-write-applier.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +28 -0
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/insights.js +19 -19
- package/dist/dashboard/web/insights.js.map +1 -1
- package/dist/dashboard/web/overview-page.d.ts.map +1 -1
- package/dist/dashboard/web/overview-page.js +7 -4
- package/dist/dashboard/web/overview-page.js.map +1 -1
- package/dist/dashboard/web/schedules-page.d.ts +1 -1
- package/dist/dashboard/web/schedules-page.d.ts.map +1 -1
- package/dist/dashboard/web/schedules-page.js +7 -3
- package/dist/dashboard/web/schedules-page.js.map +1 -1
- package/dist/dashboard/web/sessions.js +2 -2
- package/dist/dashboard/web/settings-page.d.ts +9 -0
- package/dist/dashboard/web/settings-page.d.ts.map +1 -1
- package/dist/dashboard/web/settings-page.js +132 -43
- package/dist/dashboard/web/settings-page.js.map +1 -1
- package/dist/dashboard/web/store.d.ts +6 -0
- package/dist/dashboard/web/store.d.ts.map +1 -1
- package/dist/dashboard/web/store.js +18 -1
- package/dist/dashboard/web/store.js.map +1 -1
- package/dist/dashboard/webhook-routes.d.ts.map +1 -1
- package/dist/dashboard/webhook-routes.js +24 -0
- package/dist/dashboard/webhook-routes.js.map +1 -1
- package/dist/dashboard-web/app.js +3 -3
- package/dist/dashboard-web/chunks/{bot-defaults-page-Z36I5CKM.js → bot-defaults-page-3OIY7N76.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-2BBCKWNO.js → chunk-BNEXMNQD.js} +3 -3
- package/dist/dashboard-web/chunks/{chunk-QDKIUULH.js → chunk-DKKOGZCG.js} +1 -1
- package/dist/dashboard-web/chunks/chunk-LXIK7OUJ.js +1 -0
- package/dist/dashboard-web/chunks/{chunk-BAMNP73K.js → chunk-VFCACTRF.js} +1 -1
- package/dist/dashboard-web/chunks/{connectors-I3MGERCM.js → connectors-VDOAKUW3.js} +1 -1
- package/dist/dashboard-web/chunks/{groups-page-DTP2L4FQ.js → groups-page-CX5AN4XG.js} +1 -1
- package/dist/dashboard-web/chunks/{insights-page-FNI24WYF.js → insights-page-DOMRL4S6.js} +1 -1
- package/dist/dashboard-web/chunks/overview-page-AZBAXVZ7.js +1 -0
- package/dist/dashboard-web/chunks/{roles-page-A5DZ7Q6U.js → roles-page-3FEAH6S4.js} +1 -1
- package/dist/dashboard-web/chunks/schedules-CTQEA7IE.js +1 -0
- package/dist/dashboard-web/chunks/{sessions-YJ735IH4.js → sessions-LVZCXO2Z.js} +1 -1
- package/dist/dashboard-web/chunks/{sessions-page-2REIJ56C.js → sessions-page-NHBJDSBC.js} +1 -1
- package/dist/dashboard-web/chunks/settings-page-CRDIHRNE.js +2 -0
- package/dist/dashboard-web/chunks/{skills-page-ZCCLHWMJ.js → skills-page-VUG3EPWX.js} +1 -1
- package/dist/dashboard-web/chunks/{team-federation-page-4FCGO3WW.js → team-federation-page-ZKL3YMGN.js} +1 -1
- package/dist/dashboard-web/chunks/{workflows-KFJ7O57L.js → workflows-4BYQQBFP.js} +1 -1
- package/dist/dashboard-web/index.html +1 -1
- package/dist/dashboard-web/style.css +111 -16
- package/dist/dashboard.js +196 -2
- package/dist/dashboard.js.map +1 -1
- package/dist/global-config.d.ts +30 -0
- package/dist/global-config.d.ts.map +1 -1
- package/dist/global-config.js +64 -1
- package/dist/global-config.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +10 -7
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +10 -7
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts +1 -1
- package/dist/im/lark/card-builder.js +1 -1
- package/dist/im/lark/card-handler.d.ts +3 -0
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +8 -0
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +1 -0
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +19 -0
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +10 -0
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +100 -21
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/grant-command.d.ts +1 -1
- package/dist/im/lark/grant-command.js +1 -1
- package/dist/im/lark/workflow-slash-command.js +4 -0
- package/dist/im/lark/workflow-slash-command.js.map +1 -1
- package/dist/mir-prompt.d.ts +16 -0
- package/dist/mir-prompt.d.ts.map +1 -0
- package/dist/mir-prompt.js +170 -0
- package/dist/mir-prompt.js.map +1 -0
- package/dist/mir-runner.js +1 -149
- package/dist/mir-runner.js.map +1 -1
- package/dist/platform/bind.d.ts.map +1 -1
- package/dist/platform/bind.js +3 -11
- package/dist/platform/bind.js.map +1 -1
- package/dist/platform/binding.d.ts +4 -5
- package/dist/platform/binding.d.ts.map +1 -1
- package/dist/platform/binding.js +0 -11
- package/dist/platform/binding.js.map +1 -1
- package/dist/platform/tunnel-client.d.ts.map +1 -1
- package/dist/platform/tunnel-client.js +37 -28
- package/dist/platform/tunnel-client.js.map +1 -1
- package/dist/services/deployment-identity.d.ts +1 -1
- package/dist/services/deployment-identity.d.ts.map +1 -1
- package/dist/services/deployment-identity.js +1 -1
- package/dist/services/deployment-identity.js.map +1 -1
- package/dist/services/doc-subs-store.js +1 -1
- package/dist/services/team-board-store.js +1 -1
- package/dist/services/team-board-store.js.map +1 -1
- package/dist/services/trigger-types.d.ts +2 -1
- package/dist/services/trigger-types.d.ts.map +1 -1
- package/dist/services/trigger-types.js +11 -2
- package/dist/services/trigger-types.js.map +1 -1
- package/dist/services/vc-meeting-runtime-store.d.ts +55 -0
- package/dist/services/vc-meeting-runtime-store.d.ts.map +1 -0
- package/dist/services/vc-meeting-runtime-store.js +313 -0
- package/dist/services/vc-meeting-runtime-store.js.map +1 -0
- package/dist/services/voice/index.d.ts +6 -1
- package/dist/services/voice/index.d.ts.map +1 -1
- package/dist/services/voice/index.js +12 -5
- package/dist/services/voice/index.js.map +1 -1
- package/dist/services/voice/sami.js +1 -1
- package/dist/setup/lark-scopes.json +5 -0
- package/dist/setup/verify-permissions.d.ts +6 -0
- package/dist/setup/verify-permissions.d.ts.map +1 -1
- package/dist/setup/verify-permissions.js +17 -0
- package/dist/setup/verify-permissions.js.map +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +10 -0
- package/dist/skills/definitions.js.map +1 -1
- package/dist/utils/daemon-discovery.d.ts +2 -0
- package/dist/utils/daemon-discovery.d.ts.map +1 -1
- package/dist/utils/daemon-discovery.js +2 -0
- package/dist/utils/daemon-discovery.js.map +1 -1
- package/dist/utils/timezone.d.ts +51 -0
- package/dist/utils/timezone.d.ts.map +1 -0
- package/dist/utils/timezone.js +110 -0
- package/dist/utils/timezone.js.map +1 -0
- package/dist/vc-agent/cards.d.ts +47 -0
- package/dist/vc-agent/cards.d.ts.map +1 -0
- package/dist/vc-agent/cards.js +489 -0
- package/dist/vc-agent/cards.js.map +1 -0
- package/dist/vc-agent/meeting-state.d.ts +39 -0
- package/dist/vc-agent/meeting-state.d.ts.map +1 -0
- package/dist/vc-agent/meeting-state.js +186 -0
- package/dist/vc-agent/meeting-state.js.map +1 -0
- package/dist/vc-agent/normalizer.d.ts +13 -0
- package/dist/vc-agent/normalizer.d.ts.map +1 -0
- package/dist/vc-agent/normalizer.js +411 -0
- package/dist/vc-agent/normalizer.js.map +1 -0
- package/dist/vc-agent/polling-source.d.ts +36 -0
- package/dist/vc-agent/polling-source.d.ts.map +1 -0
- package/dist/vc-agent/polling-source.js +129 -0
- package/dist/vc-agent/polling-source.js.map +1 -0
- package/dist/vc-agent/push-source.d.ts +13 -0
- package/dist/vc-agent/push-source.d.ts.map +1 -0
- package/dist/vc-agent/push-source.js +109 -0
- package/dist/vc-agent/push-source.js.map +1 -0
- package/dist/vc-agent/realtime/audio-source.d.ts +6 -0
- package/dist/vc-agent/realtime/audio-source.d.ts.map +1 -0
- package/dist/vc-agent/realtime/audio-source.js +17 -0
- package/dist/vc-agent/realtime/audio-source.js.map +1 -0
- package/dist/vc-agent/realtime/endpoint.d.ts +6 -0
- package/dist/vc-agent/realtime/endpoint.d.ts.map +1 -0
- package/dist/vc-agent/realtime/endpoint.js +25 -0
- package/dist/vc-agent/realtime/endpoint.js.map +1 -0
- package/dist/vc-agent/realtime/errors.d.ts +9 -0
- package/dist/vc-agent/realtime/errors.d.ts.map +1 -0
- package/dist/vc-agent/realtime/errors.js +17 -0
- package/dist/vc-agent/realtime/errors.js.map +1 -0
- package/dist/vc-agent/realtime/events.d.ts +24 -0
- package/dist/vc-agent/realtime/events.d.ts.map +1 -0
- package/dist/vc-agent/realtime/events.js +190 -0
- package/dist/vc-agent/realtime/events.js.map +1 -0
- package/dist/vc-agent/realtime/frontier.d.ts +34 -0
- package/dist/vc-agent/realtime/frontier.d.ts.map +1 -0
- package/dist/vc-agent/realtime/frontier.js +40 -0
- package/dist/vc-agent/realtime/frontier.js.map +1 -0
- package/dist/vc-agent/realtime/index.d.ts +11 -0
- package/dist/vc-agent/realtime/index.d.ts.map +1 -0
- package/dist/vc-agent/realtime/index.js +11 -0
- package/dist/vc-agent/realtime/index.js.map +1 -0
- package/dist/vc-agent/realtime/pacer.d.ts +21 -0
- package/dist/vc-agent/realtime/pacer.d.ts.map +1 -0
- package/dist/vc-agent/realtime/pacer.js +80 -0
- package/dist/vc-agent/realtime/pacer.js.map +1 -0
- package/dist/vc-agent/realtime/protobuf.d.ts +33 -0
- package/dist/vc-agent/realtime/protobuf.d.ts.map +1 -0
- package/dist/vc-agent/realtime/protobuf.js +159 -0
- package/dist/vc-agent/realtime/protobuf.js.map +1 -0
- package/dist/vc-agent/realtime/protocol.d.ts +4 -0
- package/dist/vc-agent/realtime/protocol.d.ts.map +1 -0
- package/dist/vc-agent/realtime/protocol.js +59 -0
- package/dist/vc-agent/realtime/protocol.js.map +1 -0
- package/dist/vc-agent/realtime/session.d.ts +39 -0
- package/dist/vc-agent/realtime/session.d.ts.map +1 -0
- package/dist/vc-agent/realtime/session.js +221 -0
- package/dist/vc-agent/realtime/session.js.map +1 -0
- package/dist/vc-agent/realtime/transport.d.ts +23 -0
- package/dist/vc-agent/realtime/transport.d.ts.map +1 -0
- package/dist/vc-agent/realtime/transport.js +112 -0
- package/dist/vc-agent/realtime/transport.js.map +1 -0
- package/dist/vc-agent/realtime/types.d.ts +84 -0
- package/dist/vc-agent/realtime/types.d.ts.map +1 -0
- package/dist/vc-agent/realtime/types.js +5 -0
- package/dist/vc-agent/realtime/types.js.map +1 -0
- package/dist/vc-agent/types.d.ts +142 -0
- package/dist/vc-agent/types.d.ts.map +1 -0
- package/dist/vc-agent/types.js +2 -0
- package/dist/vc-agent/types.js.map +1 -0
- package/dist/worker.js +3 -3
- package/dist/worker.js.map +1 -1
- package/dist/workflows/attempt-resume.d.ts +4 -0
- package/dist/workflows/attempt-resume.d.ts.map +1 -1
- package/dist/workflows/attempt-resume.js +2 -0
- package/dist/workflows/attempt-resume.js.map +1 -1
- package/dist/workflows/attempt-terminal.d.ts +4 -0
- package/dist/workflows/attempt-terminal.d.ts.map +1 -1
- package/dist/workflows/attempt-terminal.js.map +1 -1
- package/dist/workflows/daemon-spawn.d.ts.map +1 -1
- package/dist/workflows/daemon-spawn.js +7 -0
- package/dist/workflows/daemon-spawn.js.map +1 -1
- package/dist/workflows/events/payloads.d.ts +32 -0
- package/dist/workflows/events/payloads.d.ts.map +1 -1
- package/dist/workflows/events/payloads.js +4 -0
- package/dist/workflows/events/payloads.js.map +1 -1
- package/dist/workflows/events/schema.d.ts +56 -0
- package/dist/workflows/events/schema.d.ts.map +1 -1
- package/dist/workflows/runtime.d.ts +4 -0
- package/dist/workflows/runtime.d.ts.map +1 -1
- package/dist/workflows/runtime.js.map +1 -1
- package/dist/workflows/spawn-policy.d.ts +14 -0
- package/dist/workflows/spawn-policy.d.ts.map +1 -0
- package/dist/workflows/spawn-policy.js +9 -0
- package/dist/workflows/spawn-policy.js.map +1 -0
- package/dist/workflows/v3/bot-resolve.d.ts.map +1 -1
- package/dist/workflows/v3/bot-resolve.js +4 -0
- package/dist/workflows/v3/bot-resolve.js.map +1 -1
- package/dist/workflows/v3/cli-run.d.ts.map +1 -1
- package/dist/workflows/v3/cli-run.js +4 -0
- package/dist/workflows/v3/cli-run.js.map +1 -1
- package/dist/workflows/v3/contract.d.ts +9 -3
- package/dist/workflows/v3/contract.d.ts.map +1 -1
- package/dist/workflows/v3/contract.js +3 -3
- package/dist/workflows/v3/contract.js.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.d.ts.map +1 -1
- package/dist/workflows/v3/ephemeral-pool.js +2 -0
- package/dist/workflows/v3/ephemeral-pool.js.map +1 -1
- package/dist/workflows/v3/runtime.js +1 -1
- package/dist/workflows/v3/runtime.js.map +1 -1
- package/package.json +1 -1
- package/dist/dashboard-web/chunks/chunk-76J7PNZI.js +0 -1
- package/dist/dashboard-web/chunks/overview-page-EHCZJBWY.js +0 -1
- package/dist/dashboard-web/chunks/schedules-RSXALJU4.js +0 -1
- 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
|