botmux 3.7.1 → 3.8.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/dist/.runtime-build-id +1 -1
- package/dist/adapters/backend/capabilities.d.ts +17 -0
- package/dist/adapters/backend/capabilities.d.ts.map +1 -0
- package/dist/adapters/backend/capabilities.js +22 -0
- package/dist/adapters/backend/capabilities.js.map +1 -0
- package/dist/adapters/backend/critical-control-key.d.ts +19 -0
- package/dist/adapters/backend/critical-control-key.d.ts.map +1 -0
- package/dist/adapters/backend/critical-control-key.js +34 -0
- package/dist/adapters/backend/critical-control-key.js.map +1 -0
- package/dist/adapters/backend/herdr-backend.d.ts +9 -0
- package/dist/adapters/backend/herdr-backend.d.ts.map +1 -1
- package/dist/adapters/backend/herdr-backend.js +23 -4
- package/dist/adapters/backend/herdr-backend.js.map +1 -1
- package/dist/adapters/backend/riff-backend.d.ts.map +1 -1
- package/dist/adapters/backend/riff-backend.js +3 -2
- package/dist/adapters/backend/riff-backend.js.map +1 -1
- package/dist/adapters/backend/session-backend-selector.d.ts +61 -6
- package/dist/adapters/backend/session-backend-selector.d.ts.map +1 -1
- package/dist/adapters/backend/session-backend-selector.js +173 -9
- package/dist/adapters/backend/session-backend-selector.js.map +1 -1
- package/dist/adapters/backend/tmux-backend.d.ts +10 -3
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-backend.js +25 -8
- package/dist/adapters/backend/tmux-backend.js.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.js +3 -2
- package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
- package/dist/adapters/backend/types.d.ts +45 -4
- package/dist/adapters/backend/types.d.ts.map +1 -1
- package/dist/adapters/backend/types.js +11 -0
- package/dist/adapters/backend/types.js.map +1 -1
- package/dist/adapters/backend/zellij-backend.d.ts.map +1 -1
- package/dist/adapters/backend/zellij-backend.js +3 -2
- package/dist/adapters/backend/zellij-backend.js.map +1 -1
- package/dist/adapters/backend/zmx-backend.d.ts +286 -0
- package/dist/adapters/backend/zmx-backend.d.ts.map +1 -0
- package/dist/adapters/backend/zmx-backend.js +2396 -0
- package/dist/adapters/backend/zmx-backend.js.map +1 -0
- package/dist/adapters/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +3 -0
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/adapters/cli/codex-app.d.ts.map +1 -1
- package/dist/adapters/cli/codex-app.js +5 -1
- package/dist/adapters/cli/codex-app.js.map +1 -1
- package/dist/adapters/cli/codex.d.ts.map +1 -1
- package/dist/adapters/cli/codex.js +26 -1
- package/dist/adapters/cli/codex.js.map +1 -1
- package/dist/adapters/cli/fs-policy.d.ts +79 -1
- package/dist/adapters/cli/fs-policy.d.ts.map +1 -1
- package/dist/adapters/cli/fs-policy.js +290 -13
- package/dist/adapters/cli/fs-policy.js.map +1 -1
- package/dist/adapters/cli/grok.d.ts.map +1 -1
- package/dist/adapters/cli/grok.js +4 -1
- package/dist/adapters/cli/grok.js.map +1 -1
- package/dist/adapters/cli/oh-my-pi.d.ts.map +1 -1
- package/dist/adapters/cli/oh-my-pi.js +5 -3
- package/dist/adapters/cli/oh-my-pi.js.map +1 -1
- package/dist/adapters/cli/shared-hints.d.ts +7 -4
- package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
- package/dist/adapters/cli/shared-hints.js +52 -35
- package/dist/adapters/cli/shared-hints.js.map +1 -1
- package/dist/adapters/cli/strict-input-handle.d.ts +13 -0
- package/dist/adapters/cli/strict-input-handle.d.ts.map +1 -0
- package/dist/adapters/cli/strict-input-handle.js +39 -0
- package/dist/adapters/cli/strict-input-handle.js.map +1 -0
- package/dist/adapters/cli/traex.d.ts.map +1 -1
- package/dist/adapters/cli/traex.js +6 -4
- package/dist/adapters/cli/traex.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +16 -0
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/bot-registry.d.ts +137 -8
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +298 -12
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/session-list-liveness.d.ts +1 -1
- package/dist/cli/session-list-liveness.js +1 -1
- package/dist/cli/zmx-managed-attach.d.ts +41 -0
- package/dist/cli/zmx-managed-attach.d.ts.map +1 -0
- package/dist/cli/zmx-managed-attach.js +72 -0
- package/dist/cli/zmx-managed-attach.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +780 -131
- package/dist/cli.js.map +1 -1
- package/dist/codex-app-runner.js +90 -2
- package/dist/codex-app-runner.js.map +1 -1
- package/dist/codex-rpc-engine.d.ts.map +1 -1
- package/dist/codex-rpc-engine.js +22 -6
- package/dist/codex-rpc-engine.js.map +1 -1
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +29 -1
- package/dist/config.js.map +1 -1
- package/dist/core/ask-broker.d.ts +22 -1
- package/dist/core/ask-broker.d.ts.map +1 -1
- package/dist/core/ask-broker.js +12 -5
- package/dist/core/ask-broker.js.map +1 -1
- package/dist/core/botmux-wrapper.d.ts +18 -0
- package/dist/core/botmux-wrapper.d.ts.map +1 -1
- package/dist/core/botmux-wrapper.js +25 -1
- package/dist/core/botmux-wrapper.js.map +1 -1
- package/dist/core/chat-rename.d.ts +27 -0
- package/dist/core/chat-rename.d.ts.map +1 -0
- package/dist/core/chat-rename.js +53 -0
- package/dist/core/chat-rename.js.map +1 -0
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +160 -12
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/cost-calculator.d.ts +25 -1
- package/dist/core/cost-calculator.d.ts.map +1 -1
- package/dist/core/cost-calculator.js +102 -4
- package/dist/core/cost-calculator.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts +16 -2
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +611 -62
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dashboard-rows.d.ts +22 -1
- package/dist/core/dashboard-rows.d.ts.map +1 -1
- package/dist/core/dashboard-rows.js +61 -0
- package/dist/core/dashboard-rows.js.map +1 -1
- package/dist/core/dashboard-url.d.ts +6 -0
- package/dist/core/dashboard-url.d.ts.map +1 -1
- package/dist/core/dashboard-url.js +11 -1
- package/dist/core/dashboard-url.js.map +1 -1
- package/dist/core/device-isolation-daemon.d.ts +28 -6
- package/dist/core/device-isolation-daemon.d.ts.map +1 -1
- package/dist/core/device-isolation-daemon.js +96 -13
- package/dist/core/device-isolation-daemon.js.map +1 -1
- package/dist/core/host-overload-alert.d.ts +75 -0
- package/dist/core/host-overload-alert.d.ts.map +1 -1
- package/dist/core/host-overload-alert.js +103 -0
- package/dist/core/host-overload-alert.js.map +1 -1
- package/dist/core/idle-worker-sweeper.js +1 -1
- package/dist/core/idle-worker-sweeper.js.map +1 -1
- package/dist/core/inflight-input-tracker.d.ts +3 -0
- package/dist/core/inflight-input-tracker.d.ts.map +1 -1
- package/dist/core/inflight-input-tracker.js +9 -0
- package/dist/core/inflight-input-tracker.js.map +1 -1
- package/dist/core/passthrough-commands.d.ts.map +1 -1
- package/dist/core/passthrough-commands.js +10 -0
- package/dist/core/passthrough-commands.js.map +1 -1
- package/dist/core/persistent-backend.d.ts +32 -4
- package/dist/core/persistent-backend.d.ts.map +1 -1
- package/dist/core/persistent-backend.js +75 -6
- package/dist/core/persistent-backend.js.map +1 -1
- package/dist/core/plugins/mcp/gateway.js +2 -2
- package/dist/core/plugins/mcp/gateway.js.map +1 -1
- package/dist/core/plugins/runtime.d.ts +3 -0
- package/dist/core/plugins/runtime.d.ts.map +1 -1
- package/dist/core/plugins/runtime.js.map +1 -1
- package/dist/core/plugins/service-manager.d.ts +4 -1
- package/dist/core/plugins/service-manager.d.ts.map +1 -1
- package/dist/core/plugins/service-manager.js +11 -6
- package/dist/core/plugins/service-manager.js.map +1 -1
- package/dist/core/role-library.d.ts +48 -1
- package/dist/core/role-library.d.ts.map +1 -1
- package/dist/core/role-library.js +111 -3
- package/dist/core/role-library.js.map +1 -1
- package/dist/core/role-resolver.d.ts +14 -2
- package/dist/core/role-resolver.d.ts.map +1 -1
- package/dist/core/role-resolver.js +47 -4
- package/dist/core/role-resolver.js.map +1 -1
- package/dist/core/session-activity.d.ts +14 -0
- package/dist/core/session-activity.d.ts.map +1 -1
- package/dist/core/session-activity.js +46 -1
- package/dist/core/session-activity.js.map +1 -1
- package/dist/core/session-board.d.ts +5 -2
- package/dist/core/session-board.d.ts.map +1 -1
- package/dist/core/session-board.js +5 -2
- package/dist/core/session-board.js.map +1 -1
- package/dist/core/session-liveness.d.ts +6 -5
- package/dist/core/session-liveness.d.ts.map +1 -1
- package/dist/core/session-liveness.js +34 -13
- package/dist/core/session-liveness.js.map +1 -1
- package/dist/core/session-manager.d.ts +3 -2
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +397 -103
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-marker.d.ts +11 -2
- package/dist/core/session-marker.d.ts.map +1 -1
- package/dist/core/session-marker.js +50 -11
- package/dist/core/session-marker.js.map +1 -1
- package/dist/core/session-message-preview.d.ts +20 -0
- package/dist/core/session-message-preview.d.ts.map +1 -0
- package/dist/core/session-message-preview.js +188 -0
- package/dist/core/session-message-preview.js.map +1 -0
- package/dist/core/session-title.d.ts +5 -1
- package/dist/core/session-title.d.ts.map +1 -1
- package/dist/core/session-title.js +20 -3
- package/dist/core/session-title.js.map +1 -1
- package/dist/core/startup-commands.d.ts +1 -1
- package/dist/core/startup-commands.js +1 -1
- package/dist/core/terminal-url.d.ts.map +1 -1
- package/dist/core/terminal-url.js +3 -2
- package/dist/core/terminal-url.js.map +1 -1
- package/dist/core/trigger-session.d.ts.map +1 -1
- package/dist/core/trigger-session.js +75 -12
- package/dist/core/trigger-session.js.map +1 -1
- package/dist/core/types.d.ts +35 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +23 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-ipc.d.ts +11 -0
- package/dist/core/worker-ipc.d.ts.map +1 -0
- package/dist/core/worker-ipc.js +26 -0
- package/dist/core/worker-ipc.js.map +1 -0
- package/dist/core/worker-pool.d.ts +179 -29
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +2118 -331
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts +132 -3
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +1327 -449
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/auth.d.ts +2 -0
- package/dist/dashboard/auth.d.ts.map +1 -1
- package/dist/dashboard/auth.js +9 -0
- package/dist/dashboard/auth.js.map +1 -1
- package/dist/dashboard/bot-payload.d.ts +4 -0
- package/dist/dashboard/bot-payload.d.ts.map +1 -1
- package/dist/dashboard/bot-payload.js +5 -0
- package/dist/dashboard/bot-payload.js.map +1 -1
- package/dist/dashboard/federation-api.d.ts.map +1 -1
- package/dist/dashboard/federation-api.js +4 -0
- package/dist/dashboard/federation-api.js.map +1 -1
- package/dist/dashboard/federation-spoke-api.d.ts.map +1 -1
- package/dist/dashboard/federation-spoke-api.js +32 -5
- package/dist/dashboard/federation-spoke-api.js.map +1 -1
- package/dist/dashboard/public-redact.d.ts +8 -2
- package/dist/dashboard/public-redact.d.ts.map +1 -1
- package/dist/dashboard/public-redact.js +34 -7
- package/dist/dashboard/public-redact.js.map +1 -1
- package/dist/dashboard/session-card-model.d.ts.map +1 -1
- package/dist/dashboard/session-card-model.js +10 -2
- package/dist/dashboard/session-card-model.js.map +1 -1
- package/dist/dashboard/settings-write-applier.d.ts +35 -1
- package/dist/dashboard/settings-write-applier.d.ts.map +1 -1
- package/dist/dashboard/settings-write-applier.js +88 -1
- package/dist/dashboard/settings-write-applier.js.map +1 -1
- package/dist/dashboard/web/app.d.ts.map +1 -1
- package/dist/dashboard/web/app.js +0 -1
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.d.ts +15 -0
- package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.js +212 -58
- package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
- package/dist/dashboard/web/bot-defaults.d.ts +3 -0
- package/dist/dashboard/web/bot-defaults.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults.js.map +1 -1
- package/dist/dashboard/web/bot-onboarding.d.ts +2 -1
- package/dist/dashboard/web/bot-onboarding.d.ts.map +1 -1
- package/dist/dashboard/web/bot-onboarding.js.map +1 -1
- package/dist/dashboard/web/clipboard.d.ts +2 -0
- package/dist/dashboard/web/clipboard.d.ts.map +1 -0
- package/dist/dashboard/web/clipboard.js +42 -0
- package/dist/dashboard/web/clipboard.js.map +1 -0
- package/dist/dashboard/web/connectors-page.d.ts.map +1 -1
- package/dist/dashboard/web/connectors-page.js +12 -8
- package/dist/dashboard/web/connectors-page.js.map +1 -1
- package/dist/dashboard/web/dashboard-components.d.ts +17 -16
- package/dist/dashboard/web/dashboard-components.d.ts.map +1 -1
- package/dist/dashboard/web/dashboard-components.js.map +1 -1
- package/dist/dashboard/web/groups-page.d.ts.map +1 -1
- package/dist/dashboard/web/groups-page.js +7 -3
- package/dist/dashboard/web/groups-page.js.map +1 -1
- package/dist/dashboard/web/i18n.d.ts.map +1 -1
- package/dist/dashboard/web/i18n.js +205 -12
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/icon-tooltip.d.ts.map +1 -1
- package/dist/dashboard/web/icon-tooltip.js +16 -1
- package/dist/dashboard/web/icon-tooltip.js.map +1 -1
- package/dist/dashboard/web/listener-filters.d.ts +23 -0
- package/dist/dashboard/web/listener-filters.d.ts.map +1 -0
- package/dist/dashboard/web/listener-filters.js +36 -0
- package/dist/dashboard/web/listener-filters.js.map +1 -0
- package/dist/dashboard/web/overview-page.d.ts.map +1 -1
- package/dist/dashboard/web/overview-page.js.map +1 -1
- package/dist/dashboard/web/plugin-page.d.ts.map +1 -1
- package/dist/dashboard/web/plugin-page.js.map +1 -1
- package/dist/dashboard/web/preview-markdown.d.ts +5 -0
- package/dist/dashboard/web/preview-markdown.d.ts.map +1 -0
- package/dist/dashboard/web/preview-markdown.js +52 -0
- package/dist/dashboard/web/preview-markdown.js.map +1 -0
- package/dist/dashboard/web/roles-page.d.ts.map +1 -1
- package/dist/dashboard/web/roles-page.js +535 -10
- package/dist/dashboard/web/roles-page.js.map +1 -1
- package/dist/dashboard/web/roles.d.ts +77 -0
- package/dist/dashboard/web/roles.d.ts.map +1 -1
- package/dist/dashboard/web/roles.js +98 -0
- package/dist/dashboard/web/roles.js.map +1 -1
- package/dist/dashboard/web/session-terminal.d.ts.map +1 -1
- package/dist/dashboard/web/session-terminal.js +6 -4
- package/dist/dashboard/web/session-terminal.js.map +1 -1
- package/dist/dashboard/web/sessions-kanban.d.ts +4 -1
- package/dist/dashboard/web/sessions-kanban.d.ts.map +1 -1
- package/dist/dashboard/web/sessions-kanban.js +1 -1
- package/dist/dashboard/web/sessions-kanban.js.map +1 -1
- package/dist/dashboard/web/sessions-page.d.ts +3 -2
- package/dist/dashboard/web/sessions-page.d.ts.map +1 -1
- package/dist/dashboard/web/sessions-page.js +163 -28
- package/dist/dashboard/web/sessions-page.js.map +1 -1
- package/dist/dashboard/web/sessions.d.ts +25 -0
- package/dist/dashboard/web/sessions.d.ts.map +1 -1
- package/dist/dashboard/web/sessions.js +58 -7
- package/dist/dashboard/web/sessions.js.map +1 -1
- package/dist/dashboard/web/settings-page.d.ts +28 -3
- package/dist/dashboard/web/settings-page.d.ts.map +1 -1
- package/dist/dashboard/web/settings-page.js +61 -1
- package/dist/dashboard/web/settings-page.js.map +1 -1
- package/dist/dashboard/web/skills-page.d.ts +6 -5
- package/dist/dashboard/web/skills-page.d.ts.map +1 -1
- package/dist/dashboard/web/skills-page.js +2 -0
- package/dist/dashboard/web/skills-page.js.map +1 -1
- package/dist/dashboard/web/v3-components.d.ts +3 -2
- package/dist/dashboard/web/v3-components.d.ts.map +1 -1
- package/dist/dashboard/web/v3-components.js.map +1 -1
- package/dist/dashboard/web/vc-consumer-profiles-section.d.ts +12 -2
- package/dist/dashboard/web/vc-consumer-profiles-section.d.ts.map +1 -1
- package/dist/dashboard/web/vc-consumer-profiles-section.js +0 -9
- package/dist/dashboard/web/vc-consumer-profiles-section.js.map +1 -1
- package/dist/dashboard/web/webhook-logs-page.d.ts +2 -1
- package/dist/dashboard/web/webhook-logs-page.d.ts.map +1 -1
- package/dist/dashboard/web/webhook-logs-page.js +4 -1
- package/dist/dashboard/web/webhook-logs-page.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/bot-defaults-page-FAPIMQV3.js +10 -0
- package/dist/dashboard-web/chunks/{chunk-QFMH6ITB.js → chunk-5CJMHTT4.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-KQB42ML5.js → chunk-DLZK52JU.js} +14 -12
- package/dist/dashboard-web/chunks/chunk-FDZ7WOBW.js +16 -0
- package/dist/dashboard-web/chunks/{chunk-3QAUJXAS.js → chunk-GTAJV5YC.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-FNPGOZMX.js → chunk-IHNG6KE6.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-FLGXZJTD.js → chunk-VA6QWSGQ.js} +1 -1
- package/dist/dashboard-web/chunks/chunk-XJ7BGPJH.js +1 -0
- package/dist/dashboard-web/chunks/chunk-ZJVTGU5X.js +1 -0
- package/dist/dashboard-web/chunks/connectors-page-LKWRT3GS.js +1 -0
- package/dist/dashboard-web/chunks/groups-page-V6654ICQ.js +8 -0
- package/dist/dashboard-web/chunks/insights-page-237RMFQ5.js +7 -0
- package/dist/dashboard-web/chunks/{monitor-room-7IVIS75W.js → monitor-room-OO5Y4FRQ.js} +1 -1
- package/dist/dashboard-web/chunks/{monitoring-page-5SSJRQZF.js → monitoring-page-OUEITM5P.js} +1 -1
- package/dist/dashboard-web/chunks/{office-page-EOND3L5D.js → office-page-4KNAHQ4Q.js} +1 -1
- package/dist/dashboard-web/chunks/{overview-page-NISBVBBJ.js → overview-page-QDP4YK2S.js} +1 -1
- package/dist/dashboard-web/chunks/{plugin-page-JXC5F5YV.js → plugin-page-VEGTCEAS.js} +1 -1
- package/dist/dashboard-web/chunks/roles-page-PGXNZZNP.js +1 -0
- package/dist/dashboard-web/chunks/{schedules-page-AVOOKLUH.js → schedules-page-BJNC5TID.js} +1 -1
- package/dist/dashboard-web/chunks/sessions-page-M2ZYYCMO.js +6 -0
- package/dist/dashboard-web/chunks/settings-page-IJFZKUUW.js +2 -0
- package/dist/dashboard-web/chunks/{skills-page-5MW54PCC.js → skills-page-YRAIRZOQ.js} +3 -3
- package/dist/dashboard-web/chunks/{team-federation-page-2SNIMVXI.js → team-federation-page-DEU27GRU.js} +1 -1
- package/dist/dashboard-web/chunks/{v3-page-W6SBXXQC.js → v3-page-6KHEW2YL.js} +5 -5
- package/dist/dashboard-web/chunks/{whiteboards-page-STC54KTP.js → whiteboards-page-VDECAALH.js} +1 -1
- package/dist/dashboard-web/style.css +12545 -11432
- package/dist/dashboard.js +215 -36
- package/dist/dashboard.js.map +1 -1
- package/dist/global-config.d.ts +41 -2
- package/dist/global-config.d.ts.map +1 -1
- package/dist/global-config.js +47 -0
- package/dist/global-config.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +71 -19
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +71 -19
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/callback-button-marker.d.ts +34 -0
- package/dist/im/lark/callback-button-marker.d.ts.map +1 -0
- package/dist/im/lark/callback-button-marker.js +99 -0
- package/dist/im/lark/callback-button-marker.js.map +1 -0
- package/dist/im/lark/card-builder.d.ts +46 -10
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +299 -78
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts +3 -4
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +380 -148
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +24 -1
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +101 -8
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/doc-comment.d.ts.map +1 -1
- package/dist/im/lark/doc-comment.js +6 -1
- package/dist/im/lark/doc-comment.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +115 -3
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +534 -147
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/grant-command.d.ts +16 -12
- package/dist/im/lark/grant-command.d.ts.map +1 -1
- package/dist/im/lark/grant-command.js +48 -151
- package/dist/im/lark/grant-command.js.map +1 -1
- package/dist/im/lark/grant-pending.d.ts +12 -4
- package/dist/im/lark/grant-pending.d.ts.map +1 -1
- package/dist/im/lark/grant-pending.js +31 -8
- package/dist/im/lark/grant-pending.js.map +1 -1
- package/dist/im/lark/invite-command.d.ts +20 -0
- package/dist/im/lark/invite-command.d.ts.map +1 -0
- package/dist/im/lark/invite-command.js +239 -0
- package/dist/im/lark/invite-command.js.map +1 -0
- package/dist/im/lark/md-card.d.ts +66 -4
- package/dist/im/lark/md-card.d.ts.map +1 -1
- package/dist/im/lark/md-card.js +201 -31
- package/dist/im/lark/md-card.js.map +1 -1
- package/dist/im/lark/mention-targets.d.ts +43 -0
- package/dist/im/lark/mention-targets.d.ts.map +1 -0
- package/dist/im/lark/mention-targets.js +190 -0
- package/dist/im/lark/mention-targets.js.map +1 -0
- package/dist/im/lark/message-parser.d.ts +31 -0
- package/dist/im/lark/message-parser.d.ts.map +1 -1
- package/dist/im/lark/message-parser.js +305 -32
- package/dist/im/lark/message-parser.js.map +1 -1
- package/dist/im/lark/reply-card-footer-signature.d.ts +7 -0
- package/dist/im/lark/reply-card-footer-signature.d.ts.map +1 -0
- package/dist/im/lark/reply-card-footer-signature.js +7 -0
- package/dist/im/lark/reply-card-footer-signature.js.map +1 -0
- package/dist/im/lark/sessions-card.d.ts.map +1 -1
- package/dist/im/lark/sessions-card.js +4 -1
- package/dist/im/lark/sessions-card.js.map +1 -1
- package/dist/im/lark/substitute-command.d.ts.map +1 -1
- package/dist/im/lark/substitute-command.js +8 -0
- package/dist/im/lark/substitute-command.js.map +1 -1
- package/dist/im/lark/topic-root-context.d.ts +35 -0
- package/dist/im/lark/topic-root-context.d.ts.map +1 -0
- package/dist/im/lark/topic-root-context.js +37 -0
- package/dist/im/lark/topic-root-context.js.map +1 -0
- package/dist/im/lark/v3-blocked-card.d.ts.map +1 -1
- package/dist/im/lark/v3-blocked-card.js +2 -1
- package/dist/im/lark/v3-blocked-card.js.map +1 -1
- package/dist/im/lark/v3-gate-card.d.ts.map +1 -1
- package/dist/im/lark/v3-gate-card.js +2 -1
- package/dist/im/lark/v3-gate-card.js.map +1 -1
- package/dist/im/lark/v3-loop-grant-card.d.ts.map +1 -1
- package/dist/im/lark/v3-loop-grant-card.js +2 -1
- package/dist/im/lark/v3-loop-grant-card.js.map +1 -1
- package/dist/im/lark/v3-progress-card.d.ts.map +1 -1
- package/dist/im/lark/v3-progress-card.js +2 -1
- package/dist/im/lark/v3-progress-card.js.map +1 -1
- package/dist/im/lark/v3-revisit-grant-card.d.ts.map +1 -1
- package/dist/im/lark/v3-revisit-grant-card.js +2 -1
- package/dist/im/lark/v3-revisit-grant-card.js.map +1 -1
- package/dist/index-core-only.d.ts +3 -0
- package/dist/index-core-only.d.ts.map +1 -0
- package/dist/index-core-only.js +107 -0
- package/dist/index-core-only.js.map +1 -0
- package/dist/services/async-trigger-state.d.ts +8 -0
- package/dist/services/async-trigger-state.d.ts.map +1 -1
- package/dist/services/async-trigger-state.js +3 -2
- package/dist/services/async-trigger-state.js.map +1 -1
- package/dist/services/async-trigger-store.d.ts +10 -2
- package/dist/services/async-trigger-store.d.ts.map +1 -1
- package/dist/services/async-trigger-store.js +3 -2
- package/dist/services/async-trigger-store.js.map +1 -1
- package/dist/services/backend-availability.d.ts +3 -1
- package/dist/services/backend-availability.d.ts.map +1 -1
- package/dist/services/backend-availability.js +14 -1
- package/dist/services/backend-availability.js.map +1 -1
- package/dist/services/backend-type-store.d.ts.map +1 -1
- package/dist/services/backend-type-store.js +1 -1
- package/dist/services/backend-type-store.js.map +1 -1
- package/dist/services/bot-config-store.d.ts.map +1 -1
- package/dist/services/bot-config-store.js +2 -1
- package/dist/services/bot-config-store.js.map +1 -1
- package/dist/services/bridge-fallback-gate.d.ts +14 -1
- package/dist/services/bridge-fallback-gate.d.ts.map +1 -1
- package/dist/services/bridge-fallback-gate.js +65 -1
- package/dist/services/bridge-fallback-gate.js.map +1 -1
- package/dist/services/card-prefs-store.d.ts +7 -2
- package/dist/services/card-prefs-store.d.ts.map +1 -1
- package/dist/services/card-prefs-store.js +30 -4
- package/dist/services/card-prefs-store.js.map +1 -1
- package/dist/services/codex-app-runner-protocol.d.ts +9 -0
- package/dist/services/codex-app-runner-protocol.d.ts.map +1 -1
- package/dist/services/codex-app-runner-protocol.js +17 -0
- package/dist/services/codex-app-runner-protocol.js.map +1 -1
- package/dist/services/codex-app-token-usage.d.ts +93 -0
- package/dist/services/codex-app-token-usage.d.ts.map +1 -0
- package/dist/services/codex-app-token-usage.js +190 -0
- package/dist/services/codex-app-token-usage.js.map +1 -0
- package/dist/services/codex-transcript.d.ts +6 -1
- package/dist/services/codex-transcript.d.ts.map +1 -1
- package/dist/services/codex-transcript.js +103 -32
- package/dist/services/codex-transcript.js.map +1 -1
- package/dist/services/federation-roster.d.ts +4 -0
- package/dist/services/federation-roster.d.ts.map +1 -1
- package/dist/services/federation-roster.js +3 -0
- package/dist/services/federation-roster.js.map +1 -1
- package/dist/services/federation-store.d.ts +6 -0
- package/dist/services/federation-store.d.ts.map +1 -1
- package/dist/services/federation-store.js.map +1 -1
- package/dist/services/grant-policy.d.ts +13 -0
- package/dist/services/grant-policy.d.ts.map +1 -0
- package/dist/services/grant-policy.js +40 -0
- package/dist/services/grant-policy.js.map +1 -0
- package/dist/services/grant-store.d.ts +24 -3
- package/dist/services/grant-store.d.ts.map +1 -1
- package/dist/services/grant-store.js +196 -12
- package/dist/services/grant-store.js.map +1 -1
- package/dist/services/groups-store.d.ts +36 -0
- package/dist/services/groups-store.d.ts.map +1 -1
- package/dist/services/groups-store.js +123 -1
- package/dist/services/groups-store.js.map +1 -1
- package/dist/services/jsonl-cursor.d.ts.map +1 -1
- package/dist/services/jsonl-cursor.js +8 -2
- package/dist/services/jsonl-cursor.js.map +1 -1
- package/dist/services/local-cli-opener.d.ts.map +1 -1
- package/dist/services/local-cli-opener.js +32 -0
- package/dist/services/local-cli-opener.js.map +1 -1
- package/dist/services/message-listener-run-preview-store.d.ts +43 -0
- package/dist/services/message-listener-run-preview-store.d.ts.map +1 -0
- package/dist/services/message-listener-run-preview-store.js +152 -0
- package/dist/services/message-listener-run-preview-store.js.map +1 -0
- package/dist/services/message-listener-store.d.ts +26 -0
- package/dist/services/message-listener-store.d.ts.map +1 -0
- package/dist/services/message-listener-store.js +138 -0
- package/dist/services/message-listener-store.js.map +1 -0
- package/dist/services/message-listener.d.ts +112 -0
- package/dist/services/message-listener.d.ts.map +1 -0
- package/dist/services/message-listener.js +391 -0
- package/dist/services/message-listener.js.map +1 -0
- package/dist/services/overload-alert-migration.d.ts +15 -0
- package/dist/services/overload-alert-migration.d.ts.map +1 -0
- package/dist/services/overload-alert-migration.js +115 -0
- package/dist/services/overload-alert-migration.js.map +1 -0
- package/dist/services/send-policy.d.ts +38 -0
- package/dist/services/send-policy.d.ts.map +1 -1
- package/dist/services/send-policy.js +34 -0
- package/dist/services/send-policy.js.map +1 -1
- package/dist/services/session-store.d.ts +12 -1
- package/dist/services/session-store.d.ts.map +1 -1
- package/dist/services/session-store.js +44 -2
- package/dist/services/session-store.js.map +1 -1
- package/dist/services/skill-registry-store.d.ts.map +1 -1
- package/dist/services/skill-registry-store.js +87 -12
- package/dist/services/skill-registry-store.js.map +1 -1
- package/dist/services/substitute-mode-normalize.d.ts +3 -0
- package/dist/services/substitute-mode-normalize.d.ts.map +1 -1
- package/dist/services/substitute-mode-normalize.js +8 -0
- package/dist/services/substitute-mode-normalize.js.map +1 -1
- package/dist/services/substitute-mode-store.d.ts.map +1 -1
- package/dist/services/substitute-mode-store.js +8 -1
- package/dist/services/substitute-mode-store.js.map +1 -1
- package/dist/services/transcript-resolver.d.ts +6 -1
- package/dist/services/transcript-resolver.d.ts.map +1 -1
- package/dist/services/transcript-resolver.js +145 -29
- package/dist/services/transcript-resolver.js.map +1 -1
- package/dist/services/trigger-types.d.ts +16 -0
- package/dist/services/trigger-types.d.ts.map +1 -1
- package/dist/services/trigger-types.js +6 -0
- package/dist/services/trigger-types.js.map +1 -1
- package/dist/setup/bot-config-editor.js +2 -2
- package/dist/setup/bot-config-editor.js.map +1 -1
- package/dist/setup/ensure-zmx.d.ts +31 -0
- package/dist/setup/ensure-zmx.d.ts.map +1 -0
- package/dist/setup/ensure-zmx.js +161 -0
- package/dist/setup/ensure-zmx.js.map +1 -0
- package/dist/setup/index.d.ts +1 -1
- package/dist/setup/index.js +1 -1
- package/dist/setup/open-platform-automation.d.ts +9 -0
- package/dist/setup/open-platform-automation.d.ts.map +1 -1
- package/dist/setup/open-platform-automation.js +15 -2
- package/dist/setup/open-platform-automation.js.map +1 -1
- package/dist/setup/setup-args.d.ts +1 -1
- package/dist/setup/setup-args.d.ts.map +1 -1
- package/dist/setup/setup-args.js +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +32 -0
- package/dist/skills/definitions.js.map +1 -1
- package/dist/skills/injection-mode.d.ts +6 -2
- package/dist/skills/injection-mode.d.ts.map +1 -1
- package/dist/skills/injection-mode.js +10 -5
- package/dist/skills/injection-mode.js.map +1 -1
- package/dist/types.d.ts +79 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/child-env.d.ts +1 -1
- package/dist/utils/child-env.d.ts.map +1 -1
- package/dist/utils/child-env.js +4 -0
- package/dist/utils/child-env.js.map +1 -1
- package/dist/utils/effort-confirm-dialog.d.ts +40 -0
- package/dist/utils/effort-confirm-dialog.d.ts.map +1 -0
- package/dist/utils/effort-confirm-dialog.js +74 -0
- package/dist/utils/effort-confirm-dialog.js.map +1 -0
- package/dist/utils/pending-input-queue.d.ts +56 -0
- package/dist/utils/pending-input-queue.d.ts.map +1 -1
- package/dist/utils/pending-input-queue.js +80 -0
- package/dist/utils/pending-input-queue.js.map +1 -1
- package/dist/utils/render-dimensions.d.ts +8 -0
- package/dist/utils/render-dimensions.d.ts.map +1 -1
- package/dist/utils/render-dimensions.js +10 -0
- package/dist/utils/render-dimensions.js.map +1 -1
- package/dist/utils/stuck-key-guard.d.ts +3 -2
- package/dist/utils/stuck-key-guard.d.ts.map +1 -1
- package/dist/utils/stuck-key-guard.js +3 -3
- package/dist/utils/stuck-key-guard.js.map +1 -1
- package/dist/utils/terminal-renderer.d.ts +6 -0
- package/dist/utils/terminal-renderer.d.ts.map +1 -1
- package/dist/utils/terminal-renderer.js +15 -0
- package/dist/utils/terminal-renderer.js.map +1 -1
- package/dist/utils/tui-input-delivery.d.ts +32 -0
- package/dist/utils/tui-input-delivery.d.ts.map +1 -0
- package/dist/utils/tui-input-delivery.js +53 -0
- package/dist/utils/tui-input-delivery.js.map +1 -0
- package/dist/utils/xml.d.ts +19 -0
- package/dist/utils/xml.d.ts.map +1 -0
- package/dist/utils/xml.js +26 -0
- package/dist/utils/xml.js.map +1 -0
- package/dist/worker.js +1852 -374
- package/dist/worker.js.map +1 -1
- package/dist/workflows/definition.d.ts +8 -8
- package/dist/workflows/events/payloads.d.ts +8 -8
- package/dist/workflows/events/schema.d.ts +160 -160
- package/dist/workflows/v3/session-relay-client.js +1 -1
- package/dist/workflows/v3/session-relay-client.js.map +1 -1
- package/dist/workflows/v3/worker-fence.d.ts.map +1 -1
- package/dist/workflows/v3/worker-fence.js +15 -10
- package/dist/workflows/v3/worker-fence.js.map +1 -1
- package/package.json +1 -1
- package/dist/dashboard-web/chunks/bot-defaults-page-UKA7K4JV.js +0 -10
- package/dist/dashboard-web/chunks/chunk-DFLNXQNT.js +0 -1
- package/dist/dashboard-web/chunks/connectors-page-A77YAB5Y.js +0 -1
- package/dist/dashboard-web/chunks/groups-page-RUZNVXQB.js +0 -8
- package/dist/dashboard-web/chunks/insights-page-RF7U7RTA.js +0 -22
- package/dist/dashboard-web/chunks/roles-page-BUMKD7Y4.js +0 -1
- package/dist/dashboard-web/chunks/sessions-page-6HLSEAB7.js +0 -2
- package/dist/dashboard-web/chunks/settings-page-MJDZHQ4X.js +0 -2
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { getBot } from '../bot-registry.js';
|
|
2
|
+
import { rmwBotEntry } from './config-store.js';
|
|
3
|
+
function stringList(raw) {
|
|
4
|
+
if (!Array.isArray(raw))
|
|
5
|
+
return undefined;
|
|
6
|
+
const values = raw
|
|
7
|
+
.map(value => typeof value === 'string' ? value.trim() : '')
|
|
8
|
+
.filter(Boolean);
|
|
9
|
+
return values.length > 0 ? [...new Set(values)] : undefined;
|
|
10
|
+
}
|
|
11
|
+
function senderTypes(raw) {
|
|
12
|
+
if (!Array.isArray(raw))
|
|
13
|
+
return undefined;
|
|
14
|
+
const values = raw
|
|
15
|
+
.map(value => value === 'app' ? 'bot' : value)
|
|
16
|
+
.filter((value) => value === 'user' || value === 'bot');
|
|
17
|
+
return values.length > 0 ? [...new Set(values)] : undefined;
|
|
18
|
+
}
|
|
19
|
+
export function sanitizeMessageListenerUpdate(raw) {
|
|
20
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw))
|
|
21
|
+
return undefined;
|
|
22
|
+
const entry = raw;
|
|
23
|
+
const enabled = entry.enabled === true;
|
|
24
|
+
const prompt = typeof entry.prompt === 'string' ? entry.prompt.trim() : '';
|
|
25
|
+
const name = typeof entry.name === 'string' && entry.name.trim() ? entry.name.trim() : undefined;
|
|
26
|
+
const replyCardTitle = typeof entry.replyCardTitle === 'string' && entry.replyCardTitle.trim()
|
|
27
|
+
? entry.replyCardTitle.trim()
|
|
28
|
+
: undefined;
|
|
29
|
+
const workingDir = typeof entry.workingDir === 'string' && entry.workingDir.trim() ? entry.workingDir.trim() : undefined;
|
|
30
|
+
const rawSender = entry.senderPolicy && typeof entry.senderPolicy === 'object' && !Array.isArray(entry.senderPolicy)
|
|
31
|
+
? entry.senderPolicy
|
|
32
|
+
: {};
|
|
33
|
+
const senderPolicy = {};
|
|
34
|
+
const mode = rawSender.mode === 'include_only' ? 'include_only' : 'all_except_excluded';
|
|
35
|
+
const includeSenderOpenIds = stringList(rawSender.includeSenderOpenIds);
|
|
36
|
+
const excludeSenderOpenIds = stringList(rawSender.excludeSenderOpenIds);
|
|
37
|
+
const includeSenderTypes = senderTypes(rawSender.includeSenderTypes);
|
|
38
|
+
const excludeSenderTypes = senderTypes(rawSender.excludeSenderTypes);
|
|
39
|
+
if (mode !== 'all_except_excluded')
|
|
40
|
+
senderPolicy.mode = mode;
|
|
41
|
+
if (includeSenderOpenIds)
|
|
42
|
+
senderPolicy.includeSenderOpenIds = includeSenderOpenIds;
|
|
43
|
+
if (excludeSenderOpenIds)
|
|
44
|
+
senderPolicy.excludeSenderOpenIds = excludeSenderOpenIds;
|
|
45
|
+
if (includeSenderTypes)
|
|
46
|
+
senderPolicy.includeSenderTypes = includeSenderTypes;
|
|
47
|
+
if (excludeSenderTypes)
|
|
48
|
+
senderPolicy.excludeSenderTypes = excludeSenderTypes;
|
|
49
|
+
if (rawSender.excludeSelf === false)
|
|
50
|
+
senderPolicy.excludeSelf = false;
|
|
51
|
+
const rawMessage = entry.messagePolicy && typeof entry.messagePolicy === 'object' && !Array.isArray(entry.messagePolicy)
|
|
52
|
+
? entry.messagePolicy
|
|
53
|
+
: {};
|
|
54
|
+
const messagePolicy = { scope: 'top_level' };
|
|
55
|
+
const includeMsgTypes = stringList(rawMessage.includeMsgTypes);
|
|
56
|
+
if (includeMsgTypes)
|
|
57
|
+
messagePolicy.includeMsgTypes = includeMsgTypes;
|
|
58
|
+
return {
|
|
59
|
+
enabled,
|
|
60
|
+
...(name ? { name } : {}),
|
|
61
|
+
...(replyCardTitle ? { replyCardTitle } : {}),
|
|
62
|
+
...(workingDir ? { workingDir } : {}),
|
|
63
|
+
prompt,
|
|
64
|
+
...(Object.keys(senderPolicy).length > 0 ? { senderPolicy } : {}),
|
|
65
|
+
messagePolicy,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export function validateMessageListenerUpdate(update) {
|
|
69
|
+
if (!update)
|
|
70
|
+
return { ok: false, reason: 'invalid_listener' };
|
|
71
|
+
if (!update.enabled)
|
|
72
|
+
return { ok: true };
|
|
73
|
+
if (!update.prompt.trim())
|
|
74
|
+
return { ok: false, reason: 'prompt_required' };
|
|
75
|
+
const mode = update.senderPolicy?.mode === 'include_only' ? 'include_only' : 'all_except_excluded';
|
|
76
|
+
if (mode === 'include_only' && (update.senderPolicy?.includeSenderOpenIds?.length ?? 0) === 0) {
|
|
77
|
+
return { ok: false, reason: 'sender_required' };
|
|
78
|
+
}
|
|
79
|
+
return { ok: true };
|
|
80
|
+
}
|
|
81
|
+
export function getMessageListenerConfig(larkAppId, chatId) {
|
|
82
|
+
try {
|
|
83
|
+
return getBot(larkAppId).config.messageListeners?.[chatId] ?? null;
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export async function updateMessageListenerConfig(larkAppId, chatId, patch) {
|
|
90
|
+
let bot;
|
|
91
|
+
try {
|
|
92
|
+
bot = getBot(larkAppId);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return { ok: false, reason: 'bot_not_registered' };
|
|
96
|
+
}
|
|
97
|
+
const normalized = patch.enabled ? {
|
|
98
|
+
enabled: true,
|
|
99
|
+
...(patch.name ? { name: patch.name } : {}),
|
|
100
|
+
...(patch.replyCardTitle ? { replyCardTitle: patch.replyCardTitle } : {}),
|
|
101
|
+
...(patch.workingDir ? { workingDir: patch.workingDir } : {}),
|
|
102
|
+
prompt: patch.prompt,
|
|
103
|
+
...(patch.senderPolicy && Object.keys(patch.senderPolicy).length > 0 ? { senderPolicy: patch.senderPolicy } : {}),
|
|
104
|
+
...(patch.messagePolicy ? { messagePolicy: { ...patch.messagePolicy, scope: 'top_level' } } : { messagePolicy: { scope: 'top_level' } }),
|
|
105
|
+
replyPolicy: { mode: 'thread', sessionMode: 'per_message' },
|
|
106
|
+
} : null;
|
|
107
|
+
const validation = validateMessageListenerUpdate(patch);
|
|
108
|
+
if (!validation.ok)
|
|
109
|
+
return { ok: false, reason: validation.reason };
|
|
110
|
+
const result = await rmwBotEntry(larkAppId, (entry) => {
|
|
111
|
+
if (!normalized) {
|
|
112
|
+
if (entry.messageListeners && typeof entry.messageListeners === 'object') {
|
|
113
|
+
delete entry.messageListeners[chatId];
|
|
114
|
+
if (Object.keys(entry.messageListeners).length === 0)
|
|
115
|
+
delete entry.messageListeners;
|
|
116
|
+
}
|
|
117
|
+
return { write: true, result: null };
|
|
118
|
+
}
|
|
119
|
+
if (!entry.messageListeners || typeof entry.messageListeners !== 'object' || Array.isArray(entry.messageListeners)) {
|
|
120
|
+
entry.messageListeners = {};
|
|
121
|
+
}
|
|
122
|
+
entry.messageListeners[chatId] = normalized;
|
|
123
|
+
return { write: true, result: normalized };
|
|
124
|
+
});
|
|
125
|
+
if (!result.ok)
|
|
126
|
+
return { ok: false, reason: result.reason };
|
|
127
|
+
if (!bot.config.messageListeners)
|
|
128
|
+
bot.config.messageListeners = {};
|
|
129
|
+
if (normalized)
|
|
130
|
+
bot.config.messageListeners[chatId] = normalized;
|
|
131
|
+
else {
|
|
132
|
+
delete bot.config.messageListeners[chatId];
|
|
133
|
+
if (Object.keys(bot.config.messageListeners).length === 0)
|
|
134
|
+
bot.config.messageListeners = undefined;
|
|
135
|
+
}
|
|
136
|
+
return { ok: true, listener: result.result };
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=message-listener-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-listener-store.js","sourceRoot":"","sources":["../../src/services/message-listener-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { type BotState, type MessageListenerConfig } from '../bot-registry.js';
|
|
2
|
+
export declare const MAX_MESSAGE_LISTENER_PROMPT_BYTES: number;
|
|
3
|
+
export type MessageListenerSenderType = 'user' | 'bot';
|
|
4
|
+
export interface MessageListenerMatch {
|
|
5
|
+
name?: string;
|
|
6
|
+
replyCardTitle?: string;
|
|
7
|
+
prompt: string;
|
|
8
|
+
workingDir?: string;
|
|
9
|
+
messageText: string;
|
|
10
|
+
messageTitle?: string;
|
|
11
|
+
msgType: string;
|
|
12
|
+
senderOpenId?: string;
|
|
13
|
+
senderName?: string;
|
|
14
|
+
senderType: MessageListenerSenderType;
|
|
15
|
+
}
|
|
16
|
+
export interface MessageListenerPreviewMatch extends MessageListenerMatch {
|
|
17
|
+
messageId: string;
|
|
18
|
+
createTime?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare const DEFAULT_MESSAGE_LISTENER_PREVIEW_LIMIT = 5;
|
|
21
|
+
export declare const MAX_MESSAGE_LISTENER_PREVIEW_LIMIT = 20;
|
|
22
|
+
export declare function listenerSenderType(raw: unknown): MessageListenerSenderType;
|
|
23
|
+
export declare function messageTypeOf(message: any): string;
|
|
24
|
+
export declare function extractListenerMessageTitle(message: any): string | undefined;
|
|
25
|
+
export declare function extractListenerMessageText(message: any): string;
|
|
26
|
+
export declare function findMessageListenerForChat(bot: BotState, chatId: string): MessageListenerConfig | undefined;
|
|
27
|
+
export declare function evaluateMessageListener(input: {
|
|
28
|
+
bot: BotState;
|
|
29
|
+
chatId: string;
|
|
30
|
+
message: any;
|
|
31
|
+
senderOpenId?: string;
|
|
32
|
+
senderName?: string;
|
|
33
|
+
senderTypeRaw?: string;
|
|
34
|
+
/**
|
|
35
|
+
* True when `senderOpenId` is a bot's app_id form that could NOT be resolved
|
|
36
|
+
* to a per-app open_id (the polled history API reports bots by app_id; a
|
|
37
|
+
* third-party bot with no cross-ref / observed mapping stays unresolved).
|
|
38
|
+
* Such a sender defeats open_id-based exclusion, so the exclude path fails
|
|
39
|
+
* closed. The caller resolves app_id→open_id where possible before this.
|
|
40
|
+
*/
|
|
41
|
+
senderIdentityUnverified?: boolean;
|
|
42
|
+
explicitlyMentionedThisBot: boolean;
|
|
43
|
+
}): MessageListenerMatch | undefined;
|
|
44
|
+
/** Raw sender fields as parsed from a message (realtime event or REST history). */
|
|
45
|
+
export interface ListenerRawSender {
|
|
46
|
+
senderOpenId?: string;
|
|
47
|
+
senderName?: string;
|
|
48
|
+
senderTypeRaw?: string;
|
|
49
|
+
senderIdType?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Canonicalize a message sender to the identity domain listener configs are
|
|
53
|
+
* keyed on (open_id). SHARED by every leg that feeds evaluateMessageListener
|
|
54
|
+
* (30s poll backfill AND dashboard preview/run-preview) so they can never
|
|
55
|
+
* diverge on identity handling.
|
|
56
|
+
*
|
|
57
|
+
* Bots are reported by app_id in the REST message-history API; a listener's
|
|
58
|
+
* sender filters store per-app open_ids. We map app_id → open_id ONLY via an
|
|
59
|
+
* authorization-grade map (see buildListenerBotAppIdToOpenId, which uses the
|
|
60
|
+
* strict resolver). A bot we cannot prove stays `identityUnverified`, so the
|
|
61
|
+
* matcher fails closed on open_id-based exclusion. Non-bot senders and bots
|
|
62
|
+
* already carrying an open_id pass through verified.
|
|
63
|
+
*/
|
|
64
|
+
export declare function resolveListenerSenderIdentity(sender: ListenerRawSender, appIdToOpenId: Map<string, string>): {
|
|
65
|
+
senderOpenId?: string;
|
|
66
|
+
identityUnverified: boolean;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Build an authorization-grade app_id → open_id map for the candidate bot
|
|
70
|
+
* senders. Uses the STRICT resolver (three-signal agreement, never the stale
|
|
71
|
+
* discovery stores) and only asks about CONFIGURED app_ids (the strict resolver
|
|
72
|
+
* rejects the whole batch on any non-configured subject, and a genuine
|
|
73
|
+
* third-party bot must stay unverified regardless). Anything unproven is absent
|
|
74
|
+
* from the map → resolveListenerSenderIdentity marks it unverified.
|
|
75
|
+
*
|
|
76
|
+
* SHARED by the poll and preview legs so both resolve identity identically.
|
|
77
|
+
*/
|
|
78
|
+
export declare function buildListenerBotAppIdToOpenId(larkAppId: string, chatId: string, candidateAppIds: Set<string>): Promise<Map<string, string>>;
|
|
79
|
+
/** Collect the app_id-form bot senders present in a message batch (the only
|
|
80
|
+
* subjects worth asking the strict resolver about). */
|
|
81
|
+
export declare function collectListenerBotAppIds(messages: any[], senderForMessage: (message: any) => ListenerRawSender): Set<string>;
|
|
82
|
+
export declare function normalizeMessageListenerPreviewLimit(raw: unknown): number;
|
|
83
|
+
export declare function previewMessageListenerMatches(input: {
|
|
84
|
+
bot: BotState;
|
|
85
|
+
chatId: string;
|
|
86
|
+
messages: any[];
|
|
87
|
+
limit: number;
|
|
88
|
+
senderForMessage(message: any): ListenerRawSender;
|
|
89
|
+
/** Authorization-grade app_id → open_id map (see buildListenerBotAppIdToOpenId).
|
|
90
|
+
* Omitted → every bot sender in app_id form is treated as unverified. */
|
|
91
|
+
appIdToOpenId?: Map<string, string>;
|
|
92
|
+
explicitlyMentionedThisBot?: (message: any, senderOpenId?: string) => boolean;
|
|
93
|
+
}): MessageListenerPreviewMatch[];
|
|
94
|
+
/**
|
|
95
|
+
* Trusted operator directive for a listener match: the admin-authored name +
|
|
96
|
+
* prompt only. Contains NO observed (untrusted) group-message bytes, so it is
|
|
97
|
+
* safe to place in a trusted application-context block (e.g. triggerSessionTurn's
|
|
98
|
+
* `<botmux_task trusted="true">`). The observed message must be delivered
|
|
99
|
+
* separately through the untrusted event channel (payload / rawText).
|
|
100
|
+
*/
|
|
101
|
+
export declare function renderMessageListenerInstruction(match: MessageListenerMatch): string;
|
|
102
|
+
/**
|
|
103
|
+
* Self-contained listener prompt for callers that feed a SINGLE string to the
|
|
104
|
+
* CLI as the whole turn (the daemon new-topic path). The trusted operator
|
|
105
|
+
* `<instruction>` and the untrusted `<observed_message>` are kept in separate
|
|
106
|
+
* blocks, and the observed body is BOTH xml-escaped AND explicitly marked
|
|
107
|
+
* `trusted="false"` so a group member cannot close `</observed_message>` /
|
|
108
|
+
* `</message_listener>` early and forge a trusted `<instruction>`. `match.prompt`
|
|
109
|
+
* stays raw because it is operator-authored config, not attacker-controlled.
|
|
110
|
+
*/
|
|
111
|
+
export declare function renderMessageListenerPrompt(match: MessageListenerMatch): string;
|
|
112
|
+
//# sourceMappingURL=message-listener.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-listener.d.ts","sourceRoot":"","sources":["../../src/services/message-listener.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { getAllBots } from '../bot-registry.js';
|
|
2
|
+
import { extractCardContent, unwrapUserDslContent } from '../im/lark/message-parser.js';
|
|
3
|
+
import { resolveCurrentChatBotOpenIdsByLarkAppIds } from '../im/lark/client.js';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
export const MAX_MESSAGE_LISTENER_PROMPT_BYTES = 32 * 1024;
|
|
6
|
+
export const DEFAULT_MESSAGE_LISTENER_PREVIEW_LIMIT = 5;
|
|
7
|
+
export const MAX_MESSAGE_LISTENER_PREVIEW_LIMIT = 20;
|
|
8
|
+
export function listenerSenderType(raw) {
|
|
9
|
+
return raw === 'app' || raw === 'bot' ? 'bot' : 'user';
|
|
10
|
+
}
|
|
11
|
+
export function messageTypeOf(message) {
|
|
12
|
+
return String(message?.message_type ?? message?.msg_type ?? '').trim() || 'text';
|
|
13
|
+
}
|
|
14
|
+
function listenerMessageRawContent(message) {
|
|
15
|
+
const content = message?.content ?? message?.body?.content;
|
|
16
|
+
return typeof content === 'string' ? content : '';
|
|
17
|
+
}
|
|
18
|
+
function listenerMessageContent(message) {
|
|
19
|
+
const content = listenerMessageRawContent(message);
|
|
20
|
+
if (!content)
|
|
21
|
+
return '';
|
|
22
|
+
return messageTypeOf(message) === 'interactive'
|
|
23
|
+
? unwrapUserDslContent(content) ?? content
|
|
24
|
+
: content;
|
|
25
|
+
}
|
|
26
|
+
function firstTrimmedString(...values) {
|
|
27
|
+
for (const value of values) {
|
|
28
|
+
if (typeof value !== 'string')
|
|
29
|
+
continue;
|
|
30
|
+
const trimmed = value.trim();
|
|
31
|
+
if (trimmed)
|
|
32
|
+
return trimmed;
|
|
33
|
+
}
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
export function extractListenerMessageTitle(message) {
|
|
37
|
+
const content = listenerMessageContent(message);
|
|
38
|
+
if (!content)
|
|
39
|
+
return undefined;
|
|
40
|
+
const msgType = messageTypeOf(message);
|
|
41
|
+
if (msgType === 'interactive') {
|
|
42
|
+
const renderedTitle = content.match(/<card\s+title=(["'])(.*?)\1/i)?.[2];
|
|
43
|
+
if (renderedTitle?.trim())
|
|
44
|
+
return renderedTitle.trim();
|
|
45
|
+
try {
|
|
46
|
+
const card = JSON.parse(content);
|
|
47
|
+
return firstTrimmedString(card?.title, card?.header?.title?.content, card?.header?.title?.i18n?.zh_cn, card?.header?.title?.i18n?.en_us);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (msgType === 'post') {
|
|
54
|
+
try {
|
|
55
|
+
const obj = JSON.parse(content);
|
|
56
|
+
const inner = obj?.zh_cn ?? obj?.en_us ?? obj;
|
|
57
|
+
return firstTrimmedString(inner?.title, obj?.title);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
export function extractListenerMessageText(message) {
|
|
66
|
+
const content = listenerMessageContent(message);
|
|
67
|
+
if (!content)
|
|
68
|
+
return '';
|
|
69
|
+
const msgType = messageTypeOf(message);
|
|
70
|
+
if (msgType === 'interactive')
|
|
71
|
+
return extractCardContent(content);
|
|
72
|
+
if (msgType === 'image') {
|
|
73
|
+
try {
|
|
74
|
+
const obj = JSON.parse(content);
|
|
75
|
+
const key = firstTrimmedString(obj?.image_key, obj?.img_key);
|
|
76
|
+
return key ? `[图片消息: ${key}]` : '[图片消息]';
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return '[图片消息]';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const obj = JSON.parse(content);
|
|
84
|
+
if (typeof obj?.text === 'string')
|
|
85
|
+
return obj.text.trim();
|
|
86
|
+
const inner = obj?.zh_cn ?? obj?.en_us ?? obj;
|
|
87
|
+
if (Array.isArray(inner?.content)) {
|
|
88
|
+
const parts = [];
|
|
89
|
+
for (const para of inner.content) {
|
|
90
|
+
if (!Array.isArray(para))
|
|
91
|
+
continue;
|
|
92
|
+
for (const node of para) {
|
|
93
|
+
if (node?.tag === 'text' && typeof node.text === 'string')
|
|
94
|
+
parts.push(node.text);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return parts.join('').trim();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return '';
|
|
102
|
+
}
|
|
103
|
+
return '';
|
|
104
|
+
}
|
|
105
|
+
function contains(list, value) {
|
|
106
|
+
return !!value && !!list && list.includes(value);
|
|
107
|
+
}
|
|
108
|
+
function senderTypeAllowed(listener, type) {
|
|
109
|
+
const policy = listener.senderPolicy;
|
|
110
|
+
if (policy?.includeSenderTypes && policy.includeSenderTypes.length > 0 && !policy.includeSenderTypes.includes(type)) {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
if (policy?.excludeSenderTypes?.includes(type))
|
|
114
|
+
return false;
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
function senderOpenIdAllowed(listener, openId, identityUnverified) {
|
|
118
|
+
const policy = listener.senderPolicy;
|
|
119
|
+
const mode = policy?.mode === 'include_only' ? 'include_only' : 'all_except_excluded';
|
|
120
|
+
if (mode === 'include_only') {
|
|
121
|
+
// Allow-list: an unverified sender (a bot whose identity could not be
|
|
122
|
+
// canonicalized to a per-app open_id) can never appear in an open_id
|
|
123
|
+
// include list, so it simply does not match — already fail-safe.
|
|
124
|
+
return contains(policy?.includeSenderOpenIds, openId);
|
|
125
|
+
}
|
|
126
|
+
// all_except_excluded: an unverified sender defeats an open_id-based
|
|
127
|
+
// exclusion (the excluded open_id would never equal an app_id form), so a
|
|
128
|
+
// blocked bot would leak through on the polled backfill path. Fail closed:
|
|
129
|
+
// when the operator has ANY open_id exclusion we cannot evaluate for this
|
|
130
|
+
// sender, refuse rather than assume "not excluded". An empty exclude list
|
|
131
|
+
// makes no open_id decision, so "listen to all (except self)" still works.
|
|
132
|
+
if (identityUnverified && (policy?.excludeSenderOpenIds?.length ?? 0) > 0) {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
return !contains(policy?.excludeSenderOpenIds, openId);
|
|
136
|
+
}
|
|
137
|
+
function msgTypeAllowed(listener, msgType) {
|
|
138
|
+
const include = listener.messagePolicy?.includeMsgTypes;
|
|
139
|
+
if (!include || include.length === 0)
|
|
140
|
+
return msgType === 'text' || msgType === 'post';
|
|
141
|
+
return include.includes(msgType);
|
|
142
|
+
}
|
|
143
|
+
export function findMessageListenerForChat(bot, chatId) {
|
|
144
|
+
const listener = bot.config.messageListeners?.[chatId];
|
|
145
|
+
if (!listener?.enabled)
|
|
146
|
+
return undefined;
|
|
147
|
+
if (!listener.prompt?.trim())
|
|
148
|
+
return undefined;
|
|
149
|
+
return listener;
|
|
150
|
+
}
|
|
151
|
+
export function evaluateMessageListener(input) {
|
|
152
|
+
if (input.explicitlyMentionedThisBot)
|
|
153
|
+
return undefined;
|
|
154
|
+
const messageId = String(input.message?.message_id ?? '');
|
|
155
|
+
const rootId = input.message?.root_id ? String(input.message.root_id) : '';
|
|
156
|
+
const threadId = input.message?.thread_id ? String(input.message.thread_id) : '';
|
|
157
|
+
const parentId = input.message?.parent_id ? String(input.message.parent_id) : '';
|
|
158
|
+
// REST history returns a top-level topic root as message_id=om_* plus
|
|
159
|
+
// thread_id=omt_*. Replies carry root_id/parent_id. Do not reject the root
|
|
160
|
+
// solely because thread_id uses a different id namespace.
|
|
161
|
+
if ((rootId && rootId !== messageId) || (parentId && parentId !== messageId))
|
|
162
|
+
return undefined;
|
|
163
|
+
if (threadId && threadId.startsWith('om_') && threadId !== messageId)
|
|
164
|
+
return undefined;
|
|
165
|
+
const listener = findMessageListenerForChat(input.bot, input.chatId);
|
|
166
|
+
if (!listener)
|
|
167
|
+
return undefined;
|
|
168
|
+
const senderType = listenerSenderType(input.senderTypeRaw);
|
|
169
|
+
// Self-exclusion must cover BOTH identity forms the bot appears under:
|
|
170
|
+
// realtime events carry the bot's open_id (ou_…), but the message-history API
|
|
171
|
+
// (polled backfill) reports the bot's own messages under its app_id
|
|
172
|
+
// (== larkAppId). Comparing only against botOpenId (an open_id) silently
|
|
173
|
+
// fails on the polled path and would let the bot's own posts self-trigger.
|
|
174
|
+
const ownIds = [input.bot.botOpenId, input.bot.config.larkAppId].filter(Boolean);
|
|
175
|
+
if ((listener.senderPolicy?.excludeSelf ?? true) && input.senderOpenId && ownIds.includes(input.senderOpenId)) {
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
if (!senderTypeAllowed(listener, senderType))
|
|
179
|
+
return undefined;
|
|
180
|
+
if (!senderOpenIdAllowed(listener, input.senderOpenId, input.senderIdentityUnverified ?? false))
|
|
181
|
+
return undefined;
|
|
182
|
+
const msgType = messageTypeOf(input.message);
|
|
183
|
+
if (!msgTypeAllowed(listener, msgType))
|
|
184
|
+
return undefined;
|
|
185
|
+
const messageText = extractListenerMessageText(input.message);
|
|
186
|
+
if (!messageText && (msgType === 'text' || msgType === 'post'))
|
|
187
|
+
return undefined;
|
|
188
|
+
const messageTitle = extractListenerMessageTitle(input.message);
|
|
189
|
+
return {
|
|
190
|
+
name: listener.name,
|
|
191
|
+
replyCardTitle: listener.replyCardTitle,
|
|
192
|
+
prompt: listener.prompt,
|
|
193
|
+
workingDir: listener.workingDir,
|
|
194
|
+
messageText,
|
|
195
|
+
messageTitle,
|
|
196
|
+
msgType,
|
|
197
|
+
senderOpenId: input.senderOpenId,
|
|
198
|
+
senderName: input.senderName,
|
|
199
|
+
senderType,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Canonicalize a message sender to the identity domain listener configs are
|
|
204
|
+
* keyed on (open_id). SHARED by every leg that feeds evaluateMessageListener
|
|
205
|
+
* (30s poll backfill AND dashboard preview/run-preview) so they can never
|
|
206
|
+
* diverge on identity handling.
|
|
207
|
+
*
|
|
208
|
+
* Bots are reported by app_id in the REST message-history API; a listener's
|
|
209
|
+
* sender filters store per-app open_ids. We map app_id → open_id ONLY via an
|
|
210
|
+
* authorization-grade map (see buildListenerBotAppIdToOpenId, which uses the
|
|
211
|
+
* strict resolver). A bot we cannot prove stays `identityUnverified`, so the
|
|
212
|
+
* matcher fails closed on open_id-based exclusion. Non-bot senders and bots
|
|
213
|
+
* already carrying an open_id pass through verified.
|
|
214
|
+
*/
|
|
215
|
+
export function resolveListenerSenderIdentity(sender, appIdToOpenId) {
|
|
216
|
+
const isBotAppId = sender.senderIdType === 'app_id'
|
|
217
|
+
|| sender.senderTypeRaw === 'app'
|
|
218
|
+
|| sender.senderTypeRaw === 'bot';
|
|
219
|
+
if (!isBotAppId) {
|
|
220
|
+
return { senderOpenId: sender.senderOpenId, identityUnverified: false };
|
|
221
|
+
}
|
|
222
|
+
// A bot with no sender id at all cannot be evaluated against open_id filters.
|
|
223
|
+
if (!sender.senderOpenId) {
|
|
224
|
+
return { senderOpenId: undefined, identityUnverified: true };
|
|
225
|
+
}
|
|
226
|
+
// Already an open_id (some history rows carry open_id for bots) → verified.
|
|
227
|
+
if (sender.senderOpenId.startsWith('ou_')) {
|
|
228
|
+
return { senderOpenId: sender.senderOpenId, identityUnverified: false };
|
|
229
|
+
}
|
|
230
|
+
const mapped = appIdToOpenId.get(sender.senderOpenId);
|
|
231
|
+
if (mapped)
|
|
232
|
+
return { senderOpenId: mapped, identityUnverified: false };
|
|
233
|
+
// app_id-form bot we could not strictly resolve: keep the app_id but flag it
|
|
234
|
+
// unverified so open_id-based exclusion fails closed.
|
|
235
|
+
return { senderOpenId: sender.senderOpenId, identityUnverified: true };
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Build an authorization-grade app_id → open_id map for the candidate bot
|
|
239
|
+
* senders. Uses the STRICT resolver (three-signal agreement, never the stale
|
|
240
|
+
* discovery stores) and only asks about CONFIGURED app_ids (the strict resolver
|
|
241
|
+
* rejects the whole batch on any non-configured subject, and a genuine
|
|
242
|
+
* third-party bot must stay unverified regardless). Anything unproven is absent
|
|
243
|
+
* from the map → resolveListenerSenderIdentity marks it unverified.
|
|
244
|
+
*
|
|
245
|
+
* SHARED by the poll and preview legs so both resolve identity identically.
|
|
246
|
+
*/
|
|
247
|
+
export async function buildListenerBotAppIdToOpenId(larkAppId, chatId, candidateAppIds) {
|
|
248
|
+
const map = new Map();
|
|
249
|
+
if (candidateAppIds.size === 0)
|
|
250
|
+
return map;
|
|
251
|
+
const configuredAppIds = new Set(getAllBots().map(b => b.config.larkAppId).filter(Boolean));
|
|
252
|
+
const subjectAppIds = [...candidateAppIds].filter(appId => configuredAppIds.has(appId));
|
|
253
|
+
if (subjectAppIds.length === 0)
|
|
254
|
+
return map;
|
|
255
|
+
try {
|
|
256
|
+
const resolution = await resolveCurrentChatBotOpenIdsByLarkAppIds(larkAppId, chatId, subjectAppIds);
|
|
257
|
+
if (resolution.ok) {
|
|
258
|
+
for (const mapping of resolution.mappings) {
|
|
259
|
+
if (mapping.larkAppId && mapping.subjectOpenId) {
|
|
260
|
+
map.set(mapping.larkAppId, mapping.subjectOpenId);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
logger.debug(`[message-listener:${larkAppId}] strict bot-id resolution declined for ${chatId.substring(0, 12)}: ${resolution.error}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
logger.debug(`[message-listener:${larkAppId}] strict bot-id resolution threw for ${chatId.substring(0, 12)}: ${err instanceof Error ? err.message : String(err)}`);
|
|
270
|
+
}
|
|
271
|
+
return map;
|
|
272
|
+
}
|
|
273
|
+
/** Collect the app_id-form bot senders present in a message batch (the only
|
|
274
|
+
* subjects worth asking the strict resolver about). */
|
|
275
|
+
export function collectListenerBotAppIds(messages, senderForMessage) {
|
|
276
|
+
const appIds = new Set();
|
|
277
|
+
for (const message of messages) {
|
|
278
|
+
const s = senderForMessage(message);
|
|
279
|
+
const isBotAppId = s.senderIdType === 'app_id' || s.senderTypeRaw === 'app' || s.senderTypeRaw === 'bot';
|
|
280
|
+
if (isBotAppId && s.senderOpenId && !s.senderOpenId.startsWith('ou_')) {
|
|
281
|
+
appIds.add(s.senderOpenId);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
return appIds;
|
|
285
|
+
}
|
|
286
|
+
export function normalizeMessageListenerPreviewLimit(raw) {
|
|
287
|
+
const value = typeof raw === 'number' ? raw : Number(raw);
|
|
288
|
+
if (!Number.isFinite(value))
|
|
289
|
+
return DEFAULT_MESSAGE_LISTENER_PREVIEW_LIMIT;
|
|
290
|
+
return Math.min(MAX_MESSAGE_LISTENER_PREVIEW_LIMIT, Math.max(1, Math.floor(value)));
|
|
291
|
+
}
|
|
292
|
+
export function previewMessageListenerMatches(input) {
|
|
293
|
+
const limit = normalizeMessageListenerPreviewLimit(input.limit);
|
|
294
|
+
const appIdToOpenId = input.appIdToOpenId ?? new Map();
|
|
295
|
+
const matches = [];
|
|
296
|
+
for (const message of input.messages) {
|
|
297
|
+
const messageId = String(message?.message_id ?? '');
|
|
298
|
+
if (!messageId)
|
|
299
|
+
continue;
|
|
300
|
+
const sender = input.senderForMessage(message);
|
|
301
|
+
const resolved = resolveListenerSenderIdentity(sender, appIdToOpenId);
|
|
302
|
+
const match = evaluateMessageListener({
|
|
303
|
+
bot: input.bot,
|
|
304
|
+
chatId: input.chatId,
|
|
305
|
+
message,
|
|
306
|
+
senderOpenId: resolved.senderOpenId,
|
|
307
|
+
senderName: sender.senderName,
|
|
308
|
+
senderTypeRaw: sender.senderTypeRaw,
|
|
309
|
+
senderIdentityUnverified: resolved.identityUnverified,
|
|
310
|
+
explicitlyMentionedThisBot: input.explicitlyMentionedThisBot?.(message, resolved.senderOpenId) ?? false,
|
|
311
|
+
});
|
|
312
|
+
if (!match)
|
|
313
|
+
continue;
|
|
314
|
+
matches.push({
|
|
315
|
+
...match,
|
|
316
|
+
messageId,
|
|
317
|
+
createTime: message?.create_time ? String(message.create_time) : undefined,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
return matches.slice(Math.max(0, matches.length - limit));
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Trusted operator directive for a listener match: the admin-authored name +
|
|
324
|
+
* prompt only. Contains NO observed (untrusted) group-message bytes, so it is
|
|
325
|
+
* safe to place in a trusted application-context block (e.g. triggerSessionTurn's
|
|
326
|
+
* `<botmux_task trusted="true">`). The observed message must be delivered
|
|
327
|
+
* separately through the untrusted event channel (payload / rawText).
|
|
328
|
+
*/
|
|
329
|
+
export function renderMessageListenerInstruction(match) {
|
|
330
|
+
return [
|
|
331
|
+
'<message_listener>',
|
|
332
|
+
match.name ? ` <name>${escapeXml(match.name)}</name>` : '',
|
|
333
|
+
' <instruction>',
|
|
334
|
+
match.prompt,
|
|
335
|
+
' </instruction>',
|
|
336
|
+
'</message_listener>',
|
|
337
|
+
].filter(Boolean).join('\n');
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Self-contained listener prompt for callers that feed a SINGLE string to the
|
|
341
|
+
* CLI as the whole turn (the daemon new-topic path). The trusted operator
|
|
342
|
+
* `<instruction>` and the untrusted `<observed_message>` are kept in separate
|
|
343
|
+
* blocks, and the observed body is BOTH xml-escaped AND explicitly marked
|
|
344
|
+
* `trusted="false"` so a group member cannot close `</observed_message>` /
|
|
345
|
+
* `</message_listener>` early and forge a trusted `<instruction>`. `match.prompt`
|
|
346
|
+
* stays raw because it is operator-authored config, not attacker-controlled.
|
|
347
|
+
*/
|
|
348
|
+
export function renderMessageListenerPrompt(match) {
|
|
349
|
+
const observedText = escapeXml(truncateUtf8(match.messageText, MAX_MESSAGE_LISTENER_PROMPT_BYTES));
|
|
350
|
+
return [
|
|
351
|
+
'<message_listener>',
|
|
352
|
+
match.name ? ` <name>${escapeXml(match.name)}</name>` : '',
|
|
353
|
+
' <instruction>',
|
|
354
|
+
match.prompt,
|
|
355
|
+
' </instruction>',
|
|
356
|
+
' <observed_message',
|
|
357
|
+
' trusted="false"',
|
|
358
|
+
` sender_type="${escapeXml(match.senderType)}"`,
|
|
359
|
+
match.senderOpenId ? ` sender_open_id="${escapeXml(match.senderOpenId)}"` : '',
|
|
360
|
+
match.senderName ? ` sender_name="${escapeXml(match.senderName)}"` : '',
|
|
361
|
+
` msg_type="${escapeXml(match.msgType)}"`,
|
|
362
|
+
match.messageTitle ? ` message_title="${escapeXml(match.messageTitle)}"` : '',
|
|
363
|
+
' >',
|
|
364
|
+
observedText,
|
|
365
|
+
' </observed_message>',
|
|
366
|
+
'</message_listener>',
|
|
367
|
+
].filter(Boolean).join('\n');
|
|
368
|
+
}
|
|
369
|
+
function truncateUtf8(s, maxBytes) {
|
|
370
|
+
if (Buffer.byteLength(s, 'utf-8') <= maxBytes)
|
|
371
|
+
return s;
|
|
372
|
+
let used = 0;
|
|
373
|
+
let out = '';
|
|
374
|
+
for (const ch of s) {
|
|
375
|
+
const n = Buffer.byteLength(ch, 'utf-8');
|
|
376
|
+
if (used + n > maxBytes)
|
|
377
|
+
break;
|
|
378
|
+
out += ch;
|
|
379
|
+
used += n;
|
|
380
|
+
}
|
|
381
|
+
return out;
|
|
382
|
+
}
|
|
383
|
+
function escapeXml(s) {
|
|
384
|
+
return s
|
|
385
|
+
.replace(/&/g, '&')
|
|
386
|
+
.replace(/</g, '<')
|
|
387
|
+
.replace(/>/g, '>')
|
|
388
|
+
.replace(/"/g, '"')
|
|
389
|
+
.replace(/'/g, ''');
|
|
390
|
+
}
|
|
391
|
+
//# sourceMappingURL=message-listener.js.map
|