botmux 3.13.0 → 3.15.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 +1 -1
- package/README.md +25 -1
- package/dist/.runtime-build-id +1 -1
- package/dist/adapters/adopt-route.d.ts +58 -0
- package/dist/adapters/adopt-route.d.ts.map +1 -1
- package/dist/adapters/adopt-route.js +136 -0
- package/dist/adapters/adopt-route.js.map +1 -1
- package/dist/adapters/backend/capabilities.js +1 -1
- package/dist/adapters/backend/capabilities.js.map +1 -1
- package/dist/adapters/backend/herdr-backend.d.ts +1 -1
- package/dist/adapters/backend/herdr-backend.d.ts.map +1 -1
- package/dist/adapters/backend/herdr-backend.js +2 -1
- package/dist/adapters/backend/herdr-backend.js.map +1 -1
- package/dist/adapters/backend/riff-backend.d.ts +97 -0
- package/dist/adapters/backend/riff-backend.d.ts.map +1 -1
- package/dist/adapters/backend/riff-backend.js +380 -66
- package/dist/adapters/backend/riff-backend.js.map +1 -1
- package/dist/adapters/backend/sandbox.d.ts +8 -0
- package/dist/adapters/backend/sandbox.d.ts.map +1 -1
- package/dist/adapters/backend/sandbox.js +16 -2
- package/dist/adapters/backend/sandbox.js.map +1 -1
- package/dist/adapters/backend/tmux-backend.d.ts +12 -13
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-backend.js +113 -53
- package/dist/adapters/backend/tmux-backend.js.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.d.ts +34 -3
- package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.js +72 -9
- package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -1
- package/dist/adapters/backend/types.d.ts +7 -0
- package/dist/adapters/backend/types.d.ts.map +1 -1
- package/dist/adapters/backend/types.js.map +1 -1
- package/dist/adapters/backend/zellij-backend.d.ts +2 -3
- package/dist/adapters/backend/zellij-backend.d.ts.map +1 -1
- package/dist/adapters/backend/zellij-backend.js +6 -13
- package/dist/adapters/backend/zellij-backend.js.map +1 -1
- package/dist/adapters/backend/zellij-observe-backend.d.ts +2 -1
- package/dist/adapters/backend/zellij-observe-backend.d.ts.map +1 -1
- package/dist/adapters/backend/zellij-observe-backend.js +6 -3
- package/dist/adapters/backend/zellij-observe-backend.js.map +1 -1
- package/dist/adapters/backend/zmx-backend.d.ts.map +1 -1
- package/dist/adapters/backend/zmx-backend.js +40 -18
- package/dist/adapters/backend/zmx-backend.js.map +1 -1
- package/dist/adapters/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +12 -1
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/adapters/cli/codex.d.ts.map +1 -1
- package/dist/adapters/cli/codex.js +3 -2
- package/dist/adapters/cli/codex.js.map +1 -1
- package/dist/adapters/cli/cursor.d.ts.map +1 -1
- package/dist/adapters/cli/cursor.js +13 -1
- package/dist/adapters/cli/cursor.js.map +1 -1
- package/dist/adapters/cli/dsh.d.ts +4 -0
- package/dist/adapters/cli/dsh.d.ts.map +1 -0
- package/dist/adapters/cli/dsh.js +100 -0
- package/dist/adapters/cli/dsh.js.map +1 -0
- package/dist/adapters/cli/fs-policy.d.ts.map +1 -1
- package/dist/adapters/cli/fs-policy.js +5 -0
- package/dist/adapters/cli/fs-policy.js.map +1 -1
- package/dist/adapters/cli/opencode.d.ts +52 -1
- package/dist/adapters/cli/opencode.d.ts.map +1 -1
- package/dist/adapters/cli/opencode.js +117 -76
- package/dist/adapters/cli/opencode.js.map +1 -1
- package/dist/adapters/cli/opencode2.d.ts +4 -0
- package/dist/adapters/cli/opencode2.d.ts.map +1 -0
- package/dist/adapters/cli/opencode2.js +137 -0
- package/dist/adapters/cli/opencode2.js.map +1 -0
- package/dist/adapters/cli/pi.d.ts +14 -1
- package/dist/adapters/cli/pi.d.ts.map +1 -1
- package/dist/adapters/cli/pi.js +21 -1
- package/dist/adapters/cli/pi.js.map +1 -1
- package/dist/adapters/cli/read-isolation.d.ts +1 -1
- package/dist/adapters/cli/read-isolation.d.ts.map +1 -1
- package/dist/adapters/cli/read-isolation.js +5 -2
- package/dist/adapters/cli/read-isolation.js.map +1 -1
- package/dist/adapters/cli/registry.d.ts +7 -1
- package/dist/adapters/cli/registry.d.ts.map +1 -1
- package/dist/adapters/cli/registry.js +19 -6
- package/dist/adapters/cli/registry.js.map +1 -1
- package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
- package/dist/adapters/cli/shared-hints.js +41 -23
- package/dist/adapters/cli/shared-hints.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +28 -3
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/adapters/hook-command.d.ts +8 -0
- package/dist/adapters/hook-command.d.ts.map +1 -1
- package/dist/adapters/hook-command.js +11 -0
- package/dist/adapters/hook-command.js.map +1 -1
- package/dist/adapters/hook-installer.d.ts +16 -1
- package/dist/adapters/hook-installer.d.ts.map +1 -1
- package/dist/adapters/hook-installer.js +232 -2
- package/dist/adapters/hook-installer.js.map +1 -1
- package/dist/bot-registry.d.ts +138 -8
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +76 -4
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/pm2-start-transaction.d.ts +14 -0
- package/dist/cli/pm2-start-transaction.d.ts.map +1 -1
- package/dist/cli/pm2-start-transaction.js +25 -9
- package/dist/cli/pm2-start-transaction.js.map +1 -1
- package/dist/cli/restart-failure-notification.d.ts +54 -0
- package/dist/cli/restart-failure-notification.d.ts.map +1 -0
- package/dist/cli/restart-failure-notification.js +142 -0
- package/dist/cli/restart-failure-notification.js.map +1 -0
- package/dist/cli/restart-failure-owner.d.ts +20 -0
- package/dist/cli/restart-failure-owner.d.ts.map +1 -0
- package/dist/cli/restart-failure-owner.js +27 -0
- package/dist/cli/restart-failure-owner.js.map +1 -0
- package/dist/cli/restart-shutdown-preflight.d.ts +24 -0
- package/dist/cli/restart-shutdown-preflight.d.ts.map +1 -0
- package/dist/cli/restart-shutdown-preflight.js +105 -0
- package/dist/cli/restart-shutdown-preflight.js.map +1 -0
- package/dist/cli/send-dispatch.d.ts +26 -0
- package/dist/cli/send-dispatch.d.ts.map +1 -1
- package/dist/cli/send-dispatch.js +30 -0
- package/dist/cli/send-dispatch.js.map +1 -1
- package/dist/cli.d.ts +4 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +673 -402
- package/dist/cli.js.map +1 -1
- package/dist/codex-app-runner.js +38 -15
- package/dist/codex-app-runner.js.map +1 -1
- package/dist/codex-rpc-lifecycle.d.ts +14 -2
- package/dist/codex-rpc-lifecycle.d.ts.map +1 -1
- package/dist/codex-rpc-lifecycle.js +13 -3
- package/dist/codex-rpc-lifecycle.js.map +1 -1
- package/dist/core/ask-broker.d.ts +3 -0
- package/dist/core/ask-broker.d.ts.map +1 -1
- package/dist/core/ask-broker.js +29 -7
- package/dist/core/ask-broker.js.map +1 -1
- package/dist/core/ask-hook/registry.d.ts.map +1 -1
- package/dist/core/ask-hook/registry.js +4 -0
- package/dist/core/ask-hook/registry.js.map +1 -1
- package/dist/core/ask-types.d.ts +5 -1
- package/dist/core/ask-types.d.ts.map +1 -1
- package/dist/core/ask-types.js.map +1 -1
- package/dist/core/browser-restart.d.ts +112 -0
- package/dist/core/browser-restart.d.ts.map +1 -0
- package/dist/core/browser-restart.js +233 -0
- package/dist/core/browser-restart.js.map +1 -0
- package/dist/core/command-discovery.d.ts.map +1 -1
- package/dist/core/command-discovery.js +4 -1
- package/dist/core/command-discovery.js.map +1 -1
- package/dist/core/command-handler.d.ts +19 -11
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +237 -43
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/current-turn-provenance.d.ts.map +1 -1
- package/dist/core/current-turn-provenance.js +7 -27
- package/dist/core/current-turn-provenance.js.map +1 -1
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -1
- package/dist/core/dashboard-ipc-server.js +359 -11
- package/dist/core/dashboard-ipc-server.js.map +1 -1
- package/dist/core/dispatch-registry.d.ts.map +1 -1
- package/dist/core/dispatch-registry.js +6 -0
- package/dist/core/dispatch-registry.js.map +1 -1
- package/dist/core/dispatch-report-binding.d.ts +31 -0
- package/dist/core/dispatch-report-binding.d.ts.map +1 -0
- package/dist/core/dispatch-report-binding.js +88 -0
- package/dist/core/dispatch-report-binding.js.map +1 -0
- package/dist/core/doc-comment-prompt.d.ts +2 -0
- package/dist/core/doc-comment-prompt.d.ts.map +1 -1
- package/dist/core/doc-comment-prompt.js +6 -0
- package/dist/core/doc-comment-prompt.js.map +1 -1
- package/dist/core/host-overload-alert.d.ts +25 -1
- package/dist/core/host-overload-alert.d.ts.map +1 -1
- package/dist/core/host-overload-alert.js +69 -8
- package/dist/core/host-overload-alert.js.map +1 -1
- package/dist/core/local-terminal-opener.js +1 -1
- package/dist/core/local-terminal-opener.js.map +1 -1
- package/dist/core/managed-origin-capability.d.ts +7 -6
- package/dist/core/managed-origin-capability.d.ts.map +1 -1
- package/dist/core/managed-origin-capability.js +32 -1
- package/dist/core/managed-origin-capability.js.map +1 -1
- package/dist/core/passthrough-commands.d.ts.map +1 -1
- package/dist/core/passthrough-commands.js +3 -2
- package/dist/core/passthrough-commands.js.map +1 -1
- package/dist/core/plugins/materializer.d.ts.map +1 -1
- package/dist/core/plugins/materializer.js +1 -0
- package/dist/core/plugins/materializer.js.map +1 -1
- package/dist/core/producer-quiescence.d.ts +70 -0
- package/dist/core/producer-quiescence.d.ts.map +1 -0
- package/dist/core/producer-quiescence.js +90 -0
- package/dist/core/producer-quiescence.js.map +1 -0
- package/dist/core/raw-command-write-options.d.ts +10 -0
- package/dist/core/raw-command-write-options.d.ts.map +1 -0
- package/dist/core/raw-command-write-options.js +23 -0
- package/dist/core/raw-command-write-options.js.map +1 -0
- package/dist/core/raw-command-writer.d.ts +4 -0
- package/dist/core/raw-command-writer.d.ts.map +1 -1
- package/dist/core/raw-command-writer.js +15 -6
- package/dist/core/raw-command-writer.js.map +1 -1
- package/dist/core/reply-target.d.ts +11 -0
- package/dist/core/reply-target.d.ts.map +1 -1
- package/dist/core/reply-target.js +22 -7
- package/dist/core/reply-target.js.map +1 -1
- package/dist/core/report-session-relay.d.ts +53 -0
- package/dist/core/report-session-relay.d.ts.map +1 -0
- package/dist/core/report-session-relay.js +116 -0
- package/dist/core/report-session-relay.js.map +1 -0
- package/dist/core/session-discovery.d.ts +5 -0
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +13 -0
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-group-birth.d.ts +7 -0
- package/dist/core/session-group-birth.d.ts.map +1 -0
- package/dist/core/session-group-birth.js +145 -0
- package/dist/core/session-group-birth.js.map +1 -0
- package/dist/core/session-manager.d.ts +16 -21
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +140 -21
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/skills/frontmatter.d.ts.map +1 -1
- package/dist/core/skills/frontmatter.js +6 -1
- package/dist/core/skills/frontmatter.js.map +1 -1
- package/dist/core/trigger-session.d.ts.map +1 -1
- package/dist/core/trigger-session.js +18 -3
- package/dist/core/trigger-session.js.map +1 -1
- package/dist/core/types.d.ts +18 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +63 -11
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +262 -21
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts +33 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +904 -147
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/auth.d.ts +20 -0
- package/dist/dashboard/auth.d.ts.map +1 -1
- package/dist/dashboard/auth.js +86 -1
- package/dist/dashboard/auth.js.map +1 -1
- package/dist/dashboard/bot-payload.d.ts +9 -0
- package/dist/dashboard/bot-payload.d.ts.map +1 -1
- package/dist/dashboard/bot-payload.js +5 -1
- package/dist/dashboard/bot-payload.js.map +1 -1
- package/dist/dashboard/federation-spoke-api.d.ts.map +1 -1
- package/dist/dashboard/federation-spoke-api.js +27 -3
- package/dist/dashboard/federation-spoke-api.js.map +1 -1
- package/dist/dashboard/feedback-analytics-api.d.ts +6 -0
- package/dist/dashboard/feedback-analytics-api.d.ts.map +1 -0
- package/dist/dashboard/feedback-analytics-api.js +39 -0
- package/dist/dashboard/feedback-analytics-api.js.map +1 -0
- package/dist/dashboard/session-action-timeout.d.ts +3 -0
- package/dist/dashboard/session-action-timeout.d.ts.map +1 -0
- package/dist/dashboard/session-action-timeout.js +12 -0
- package/dist/dashboard/session-action-timeout.js.map +1 -0
- package/dist/dashboard/vc-consumer-profiles-api.d.ts +9 -3
- package/dist/dashboard/vc-consumer-profiles-api.d.ts.map +1 -1
- package/dist/dashboard/vc-consumer-profiles-api.js +2 -1
- package/dist/dashboard/vc-consumer-profiles-api.js.map +1 -1
- package/dist/dashboard/web/app.d.ts.map +1 -1
- package/dist/dashboard/web/app.js +48 -5
- package/dist/dashboard/web/app.js.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.d.ts +11 -0
- package/dist/dashboard/web/bot-defaults-page.d.ts.map +1 -1
- package/dist/dashboard/web/bot-defaults-page.js +368 -36
- package/dist/dashboard/web/bot-defaults-page.js.map +1 -1
- package/dist/dashboard/web/bot-defaults.d.ts +8 -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/dashboard-routes.d.ts.map +1 -1
- package/dist/dashboard/web/dashboard-routes.js +1 -0
- package/dist/dashboard/web/dashboard-routes.js.map +1 -1
- package/dist/dashboard/web/feedback-page.d.ts +3 -0
- package/dist/dashboard/web/feedback-page.d.ts.map +1 -0
- package/dist/dashboard/web/feedback-page.js +34 -0
- package/dist/dashboard/web/feedback-page.js.map +1 -0
- package/dist/dashboard/web/groups-page.d.ts.map +1 -1
- package/dist/dashboard/web/groups-page.js +7 -2
- 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 +122 -22
- package/dist/dashboard/web/i18n.js.map +1 -1
- package/dist/dashboard/web/skills-page.d.ts.map +1 -1
- package/dist/dashboard/web/skills-page.js +4 -2
- package/dist/dashboard/web/skills-page.js.map +1 -1
- package/dist/dashboard/web/team-federation-page.d.ts.map +1 -1
- package/dist/dashboard/web/team-federation-page.js +26 -2
- package/dist/dashboard/web/team-federation-page.js.map +1 -1
- package/dist/dashboard/web/team-federation.d.ts +19 -0
- package/dist/dashboard/web/team-federation.d.ts.map +1 -1
- package/dist/dashboard/web/team-federation.js +3 -0
- package/dist/dashboard/web/team-federation.js.map +1 -1
- package/dist/dashboard/web/update-action.d.ts +8 -0
- package/dist/dashboard/web/update-action.d.ts.map +1 -1
- package/dist/dashboard/web/update-action.js +10 -0
- package/dist/dashboard/web/update-action.js.map +1 -1
- package/dist/dashboard/web/vc-consumer-profiles-section.d.ts.map +1 -1
- package/dist/dashboard/web/vc-consumer-profiles-section.js +58 -9
- package/dist/dashboard/web/vc-consumer-profiles-section.js.map +1 -1
- package/dist/dashboard-web/app.js +1 -1
- package/dist/dashboard-web/chunks/bot-defaults-page-65SMZ4QY.js +10 -0
- package/dist/dashboard-web/chunks/chunk-G5XGBCM6.js +1 -0
- package/dist/dashboard-web/chunks/chunk-IKN6WURK.js +1 -0
- package/dist/dashboard-web/chunks/{chunk-6JTZJRQJ.js → chunk-VMWNR3SV.js} +15 -15
- package/dist/dashboard-web/chunks/{chunk-CU4SUKK3.js → chunk-Z7B3E3US.js} +1 -1
- package/dist/dashboard-web/chunks/{chunk-5QJB24I2.js → chunk-Z7DO42GJ.js} +1 -1
- package/dist/dashboard-web/chunks/connectors-page-CPH6VVFY.js +1 -0
- package/dist/dashboard-web/chunks/feedback-page-J2FKQ3LK.js +1 -0
- package/dist/dashboard-web/chunks/groups-page-VDOOLS4M.js +8 -0
- package/dist/dashboard-web/chunks/{insights-page-EVGGJI5L.js → insights-page-A2LWTKJD.js} +1 -1
- package/dist/dashboard-web/chunks/{monitor-room-HRGR2ENP.js → monitor-room-2YR752E3.js} +1 -1
- package/dist/dashboard-web/chunks/monitoring-page-BGYSKZGM.js +2 -0
- package/dist/dashboard-web/chunks/office-page-ZZHTEAE4.js +1 -0
- package/dist/dashboard-web/chunks/overview-page-7NYPKQSB.js +1 -0
- package/dist/dashboard-web/chunks/roles-page-YUC4YLJG.js +1 -0
- package/dist/dashboard-web/chunks/schedules-page-2L2NKTDJ.js +1 -0
- package/dist/dashboard-web/chunks/{sessions-page-DXBCDWCS.js → sessions-page-DYZZMKFL.js} +1 -1
- package/dist/dashboard-web/chunks/settings-page-LIULUSMH.js +2 -0
- package/dist/dashboard-web/chunks/{skills-page-2QAVB2SA.js → skills-page-DQPBBI3T.js} +2 -2
- package/dist/dashboard-web/chunks/team-federation-page-LQKLDV4K.js +1 -0
- package/dist/dashboard-web/chunks/{v3-page-AY35LKCX.js → v3-page-RVKQIMAP.js} +1 -1
- package/dist/dashboard-web/chunks/whiteboards-page-S5K55HRZ.js +1 -0
- package/dist/dashboard-web/style.css +35 -0
- package/dist/dashboard.js +210 -13
- package/dist/dashboard.js.map +1 -1
- package/dist/desktop/shared/shell-path-probes.d.ts +1 -1
- package/dist/desktop/shared/shell-path-probes.js +2 -2
- package/dist/desktop/shared/shell-path-probes.js.map +1 -1
- package/dist/dsh-runner.d.ts +3 -0
- package/dist/dsh-runner.d.ts.map +1 -0
- package/dist/dsh-runner.js +673 -0
- package/dist/dsh-runner.js.map +1 -0
- package/dist/global-config.d.ts +24 -0
- package/dist/global-config.d.ts.map +1 -1
- package/dist/global-config.js +35 -0
- package/dist/global-config.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +39 -31
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +39 -31
- package/dist/i18n/zh.js.map +1 -1
- package/dist/im/lark/ask-card.d.ts +3 -1
- package/dist/im/lark/ask-card.d.ts.map +1 -1
- package/dist/im/lark/ask-card.js +61 -5
- package/dist/im/lark/ask-card.js.map +1 -1
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +13 -6
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts +2 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +145 -5
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +18 -0
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +41 -28
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/md-card.d.ts +18 -0
- package/dist/im/lark/md-card.d.ts.map +1 -1
- package/dist/im/lark/md-card.js +21 -0
- package/dist/im/lark/md-card.js.map +1 -1
- package/dist/im/lark/relay-target-routing.d.ts.map +1 -1
- package/dist/im/lark/relay-target-routing.js +3 -2
- package/dist/im/lark/relay-target-routing.js.map +1 -1
- package/dist/im/lark/reply-mode-command.d.ts.map +1 -1
- package/dist/im/lark/reply-mode-command.js +19 -8
- package/dist/im/lark/reply-mode-command.js.map +1 -1
- package/dist/im/lark/skill-feedback-card.d.ts +15 -0
- package/dist/im/lark/skill-feedback-card.d.ts.map +1 -0
- package/dist/im/lark/skill-feedback-card.js +149 -0
- package/dist/im/lark/skill-feedback-card.js.map +1 -0
- package/dist/services/bot-config-store.d.ts +10 -1
- package/dist/services/bot-config-store.d.ts.map +1 -1
- package/dist/services/bot-config-store.js +103 -3
- package/dist/services/bot-config-store.js.map +1 -1
- package/dist/services/bridge-fallback-gate.d.ts +29 -7
- package/dist/services/bridge-fallback-gate.d.ts.map +1 -1
- package/dist/services/bridge-fallback-gate.js +58 -16
- package/dist/services/bridge-fallback-gate.js.map +1 -1
- package/dist/services/codex-reasoning-effort.d.ts +9 -0
- package/dist/services/codex-reasoning-effort.d.ts.map +1 -0
- package/dist/services/codex-reasoning-effort.js +23 -0
- package/dist/services/codex-reasoning-effort.js.map +1 -0
- package/dist/services/codex-service-tier.d.ts +1 -1
- package/dist/services/codex-service-tier.d.ts.map +1 -1
- package/dist/services/codex-transcript.d.ts +9 -0
- package/dist/services/codex-transcript.d.ts.map +1 -1
- package/dist/services/codex-transcript.js +13 -6
- package/dist/services/codex-transcript.js.map +1 -1
- package/dist/services/feed-group-tagger.d.ts +15 -0
- package/dist/services/feed-group-tagger.d.ts.map +1 -0
- package/dist/services/feed-group-tagger.js +348 -0
- package/dist/services/feed-group-tagger.js.map +1 -0
- package/dist/services/feedback-analytics.d.ts +82 -0
- package/dist/services/feedback-analytics.d.ts.map +1 -0
- package/dist/services/feedback-analytics.js +95 -0
- package/dist/services/feedback-analytics.js.map +1 -0
- package/dist/services/feedback-outbox.d.ts +24 -0
- package/dist/services/feedback-outbox.d.ts.map +1 -0
- package/dist/services/feedback-outbox.js +12 -0
- package/dist/services/feedback-outbox.js.map +1 -0
- package/dist/services/feedback-policy-resolver.d.ts +56 -0
- package/dist/services/feedback-policy-resolver.d.ts.map +1 -0
- package/dist/services/feedback-policy-resolver.js +156 -0
- package/dist/services/feedback-policy-resolver.js.map +1 -0
- package/dist/services/feedback-policy.d.ts +41 -0
- package/dist/services/feedback-policy.d.ts.map +1 -0
- package/dist/services/feedback-policy.js +102 -0
- package/dist/services/feedback-policy.js.map +1 -0
- package/dist/services/feedback-webhook-dispatcher.d.ts +76 -0
- package/dist/services/feedback-webhook-dispatcher.d.ts.map +1 -0
- package/dist/services/feedback-webhook-dispatcher.js +237 -0
- package/dist/services/feedback-webhook-dispatcher.js.map +1 -0
- package/dist/services/grant-prefs-store.d.ts +3 -0
- package/dist/services/grant-prefs-store.d.ts.map +1 -1
- package/dist/services/grant-prefs-store.js +30 -1
- package/dist/services/grant-prefs-store.js.map +1 -1
- package/dist/services/groups-store.d.ts +14 -0
- package/dist/services/groups-store.d.ts.map +1 -1
- package/dist/services/groups-store.js +23 -0
- package/dist/services/groups-store.js.map +1 -1
- package/dist/services/local-cli-opener.d.ts +1 -1
- package/dist/services/local-cli-opener.d.ts.map +1 -1
- package/dist/services/local-cli-opener.js +2 -0
- package/dist/services/local-cli-opener.js.map +1 -1
- package/dist/services/peer-cross-ref-store.d.ts +8 -0
- package/dist/services/peer-cross-ref-store.d.ts.map +1 -0
- package/dist/services/peer-cross-ref-store.js +95 -0
- package/dist/services/peer-cross-ref-store.js.map +1 -0
- package/dist/services/pi-transcript.d.ts.map +1 -1
- package/dist/services/pi-transcript.js +10 -6
- package/dist/services/pi-transcript.js.map +1 -1
- package/dist/services/prompt-context-store.d.ts +29 -0
- package/dist/services/prompt-context-store.d.ts.map +1 -0
- package/dist/services/prompt-context-store.js +205 -0
- package/dist/services/prompt-context-store.js.map +1 -0
- package/dist/services/session-group-avatar.d.ts +6 -0
- package/dist/services/session-group-avatar.d.ts.map +1 -0
- package/dist/services/session-group-avatar.js +96 -0
- package/dist/services/session-group-avatar.js.map +1 -0
- package/dist/services/session-group-title.d.ts +47 -0
- package/dist/services/session-group-title.d.ts.map +1 -0
- package/dist/services/session-group-title.js +226 -0
- package/dist/services/session-group-title.js.map +1 -0
- package/dist/services/session-groups-store.d.ts +30 -0
- package/dist/services/session-groups-store.d.ts.map +1 -0
- package/dist/services/session-groups-store.js +132 -0
- package/dist/services/session-groups-store.js.map +1 -0
- package/dist/services/session-store.d.ts +58 -0
- package/dist/services/session-store.d.ts.map +1 -1
- package/dist/services/session-store.js +174 -0
- package/dist/services/session-store.js.map +1 -1
- package/dist/services/skill-feedback-store.d.ts +252 -0
- package/dist/services/skill-feedback-store.d.ts.map +1 -0
- package/dist/services/skill-feedback-store.js +795 -0
- package/dist/services/skill-feedback-store.js.map +1 -0
- package/dist/services/skill-registry-store.d.ts +23 -0
- package/dist/services/skill-registry-store.d.ts.map +1 -1
- package/dist/services/skill-registry-store.js +93 -7
- package/dist/services/skill-registry-store.js.map +1 -1
- package/dist/services/structured-bridge-clis.d.ts +13 -4
- package/dist/services/structured-bridge-clis.d.ts.map +1 -1
- package/dist/services/structured-bridge-clis.js +13 -3
- package/dist/services/structured-bridge-clis.js.map +1 -1
- package/dist/services/team-store.d.ts +4 -0
- package/dist/services/team-store.d.ts.map +1 -1
- package/dist/services/team-store.js +16 -0
- package/dist/services/team-store.js.map +1 -1
- package/dist/services/traex-transcript.d.ts +32 -4
- package/dist/services/traex-transcript.d.ts.map +1 -1
- package/dist/services/traex-transcript.js +116 -8
- package/dist/services/traex-transcript.js.map +1 -1
- package/dist/services/trigger-types.d.ts +1 -1
- package/dist/services/trigger-types.d.ts.map +1 -1
- package/dist/services/trigger-types.js +2 -2
- package/dist/services/trigger-types.js.map +1 -1
- package/dist/services/turn-completion-events.d.ts +57 -0
- package/dist/services/turn-completion-events.d.ts.map +1 -0
- package/dist/services/turn-completion-events.js +179 -0
- package/dist/services/turn-completion-events.js.map +1 -0
- package/dist/services/vc-meeting-consumer-isolation.d.ts +21 -12
- package/dist/services/vc-meeting-consumer-isolation.d.ts.map +1 -1
- package/dist/services/vc-meeting-consumer-isolation.js +25 -19
- package/dist/services/vc-meeting-consumer-isolation.js.map +1 -1
- package/dist/services/vc-meeting-consumer-profile-bootstrap.d.ts +8 -2
- package/dist/services/vc-meeting-consumer-profile-bootstrap.d.ts.map +1 -1
- package/dist/services/vc-meeting-consumer-profile-bootstrap.js +18 -10
- package/dist/services/vc-meeting-consumer-profile-bootstrap.js.map +1 -1
- package/dist/setup/bot-config-editor.d.ts.map +1 -1
- package/dist/setup/bot-config-editor.js +6 -0
- package/dist/setup/bot-config-editor.js.map +1 -1
- package/dist/setup/cli-availability.d.ts +2 -1
- package/dist/setup/cli-availability.d.ts.map +1 -1
- package/dist/setup/cli-availability.js +2 -1
- package/dist/setup/cli-availability.js.map +1 -1
- package/dist/setup/cli-selection.d.ts +8 -0
- package/dist/setup/cli-selection.d.ts.map +1 -1
- package/dist/setup/cli-selection.js +31 -0
- package/dist/setup/cli-selection.js.map +1 -1
- package/dist/setup/ensure-fonts.d.ts +5 -0
- package/dist/setup/ensure-fonts.d.ts.map +1 -1
- package/dist/setup/ensure-fonts.js +26 -1
- package/dist/setup/ensure-fonts.js.map +1 -1
- package/dist/setup/lark-scopes.json +3 -1
- package/dist/setup/open-platform-automation.d.ts +1 -1
- package/dist/setup/open-platform-automation.d.ts.map +1 -1
- package/dist/setup/open-platform-automation.js +15 -3
- package/dist/setup/open-platform-automation.js.map +1 -1
- package/dist/skills/definitions.d.ts +1 -1
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +9 -2
- package/dist/skills/definitions.js.map +1 -1
- package/dist/types.d.ts +11 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/bot-routing.d.ts +1 -1
- package/dist/utils/bot-routing.d.ts.map +1 -1
- package/dist/utils/bot-routing.js.map +1 -1
- package/dist/utils/user-token.d.ts +38 -0
- package/dist/utils/user-token.d.ts.map +1 -1
- package/dist/utils/user-token.js +76 -1
- package/dist/utils/user-token.js.map +1 -1
- package/dist/utils/web-terminal-scroll.d.ts +27 -0
- package/dist/utils/web-terminal-scroll.d.ts.map +1 -0
- package/dist/utils/web-terminal-scroll.js +60 -0
- package/dist/utils/web-terminal-scroll.js.map +1 -0
- package/dist/vc-agent/polling-source.d.ts +70 -0
- package/dist/vc-agent/polling-source.d.ts.map +1 -1
- package/dist/vc-agent/polling-source.js +115 -0
- package/dist/vc-agent/polling-source.js.map +1 -1
- package/dist/worker.js +469 -86
- package/dist/worker.js.map +1 -1
- package/dist/workflows/definition.d.ts +22 -22
- package/dist/workflows/events/payloads.d.ts +8 -8
- package/dist/workflows/events/schema.d.ts +20 -20
- package/dist/workflows/migration/v2-run-archive-schema.d.ts +20 -20
- package/package.json +5 -1
- package/dist/dashboard-web/chunks/bot-defaults-page-NQJFJ45Z.js +0 -10
- package/dist/dashboard-web/chunks/chunk-KEEYQ3WF.js +0 -1
- package/dist/dashboard-web/chunks/connectors-page-HADHZXXZ.js +0 -1
- package/dist/dashboard-web/chunks/groups-page-5TYF46RS.js +0 -8
- package/dist/dashboard-web/chunks/monitoring-page-LBU7TTTW.js +0 -2
- package/dist/dashboard-web/chunks/office-page-DF6RRBMN.js +0 -1
- package/dist/dashboard-web/chunks/overview-page-ZB6QH2EX.js +0 -1
- package/dist/dashboard-web/chunks/roles-page-ZBZGHIIF.js +0 -1
- package/dist/dashboard-web/chunks/schedules-page-NQVQC3QY.js +0 -1
- package/dist/dashboard-web/chunks/settings-page-E7NN4NVQ.js +0 -2
- package/dist/dashboard-web/chunks/team-federation-page-VGWL53AE.js +0 -1
- package/dist/dashboard-web/chunks/whiteboards-page-BNWUU4KG.js +0 -1
|
@@ -8,7 +8,9 @@ import { useT } from './react-hooks.js';
|
|
|
8
8
|
import { store } from './store.js';
|
|
9
9
|
import { CreateActionButton, DropdownMenu, Html, InfoTip as BaseInfoTip, LoadingState, OverflowText, RefreshIconButton, dropdownLabel, } from './dashboard-components.js';
|
|
10
10
|
import { botAvatarHtml, larkConsoleUrl, loadNameMaps, overrideBotAvatar, ui } from './ui.js';
|
|
11
|
+
import { fetchGroupsSnapshot } from './groups-api.js';
|
|
11
12
|
import { DEFAULT_GRANT_DURATION_MS, DEFAULT_GRANT_QUOTA, GRANT_DURATION_OPTIONS, MAX_GRANT_QUOTA, } from '../../services/grant-policy.js';
|
|
13
|
+
import { codexReasoningEffortsForModel } from '../../services/codex-reasoning-effort.js';
|
|
12
14
|
function runtimeDraftFromBot(bot) {
|
|
13
15
|
const runtime = bot.cliRuntime;
|
|
14
16
|
if (!runtime || typeof runtime !== 'object') {
|
|
@@ -440,7 +442,79 @@ function BotDefaultsCard(props) {
|
|
|
440
442
|
return (_jsxs("article", { className: "bd-card bd-profile", "data-appid": bot.larkAppId, children: [_jsxs("header", { className: "bd-profile-head", children: [_jsx(Html, { html: botAvatarHtml({ name, larkAppId: bot.larkAppId }) }), _jsxs("div", { className: "bd-profile-id", children: [_jsx("strong", { children: name }), _jsx("code", { children: bot.larkAppId })] })] }), _jsxs("p", { className: "hint-warn-inline", children: ["\u67E5\u8BE2\u5931\u8D25\uFF1A", bot.error] })] }));
|
|
441
443
|
}
|
|
442
444
|
const def = bot.defaultOncall ?? { enabled: false, workingDir: '', since: 0 };
|
|
443
|
-
return (_jsxs("article", { className: "bd-card bd-profile", "data-appid": bot.larkAppId, children: [_jsxs("div", { className: "bd-profile-chrome", children: [_jsxs("header", { className: "bd-profile-head", children: [_jsx(BotAvatarControl, { bot: bot, name: name, patchBot: patchBot }), _jsx("div", { className: "bd-profile-main", children: _jsx(BotProfileIdentity, { bot: bot, cli: cli, patchBot: patchBot, meta: (_jsxs(_Fragment, { children: [_jsxs("small", { className: "bd-meta-ok", children: ["\u25CF ", tr('botDefaults.metaOnline')] }), (def.since ?? 0) > 0 ? _jsxs("small", { "data-oncall-since": true, children: [tr('botDefaults.lastEnabled'), ": ", fmtSince(def.since ?? 0)] }) : null, (bot.autoboundChatCount ?? 0) > 0 ? _jsx("small", { children: tr('botDefaults.autobound', { count: bot.autoboundChatCount ?? 0 }) }) : null] })) }) })] }), _jsx(BotDefaultsTabs, { active: props.activeTab, onChange: props.onTabChange })] }), _jsxs("div", { className: "bd-body bd-tab-panels", children: [_jsx("div", { id: "bd-panel-common", role: "tabpanel", "aria-labelledby": "bd-tab-common", className: "bd-tab-panel", hidden: props.activeTab !== 'common', children: _jsxs(BdTabGrid, { children: [_jsx("section", { className: "bd-tile", children: _jsx(BotAgentSection, { bot: bot, sessionFallback: cli, cliState: cliState, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(WorkingDirSection, { bot: bot, patchBot: patchBot, putCardPref: putCardPref }) }), _jsx("section", { className: "bd-tile", children: _jsx(RoleSection, { bot: bot, patchBot: patchBot }) })] }) }), _jsx("div", { id: "bd-panel-sessions", role: "tabpanel", "aria-labelledby": "bd-tab-sessions", className: "bd-tab-panel", hidden: props.activeTab !== 'sessions', children: _jsxs(BdTabGrid, { children: [_jsx("section", { className: "bd-tile", children: _jsx(SessionModeSection, { bot: bot, patchBot: patchBot, putCardPref: putCardPref }) }), _jsx("section", { className: "bd-tile", children: _jsx(SubstituteModeSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(CrossBotSection, { bot: bot, putCardPref: putCardPref }) }), _jsx("section", { className: "bd-tile", children: _jsx(SessionCapSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(StartupCommandsSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(SummaryTriggerSection, { bot: bot, patchBot: patchBot, putCardPref: putCardPref }) })] }) }), _jsx("div", { id: "bd-panel-security", role: "tabpanel", "aria-labelledby": "bd-tab-security", className: "bd-tab-panel", hidden: props.activeTab !== 'security', children: _jsxs(BdTabGrid, { children: [bot.cliId !== 'riff' ? (_jsx("section", { className: "bd-tile", children: _jsx(SandboxSection, { bot: bot, patchBot: patchBot }) })) : null, bot.cliId !== 'riff' && bot.sandbox === true ? (_jsx("section", { className: "bd-tile bd-tile-wide", children: _jsx(SandboxPathsSection, { bot: bot, patchBot: patchBot }) })) : null, _jsx("section", { className: "bd-tile", children: _jsx(GrantSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(SlashCommandPermissionsSection, { bot: bot, patchBot: patchBot }) })] }) }), _jsx("div", { id: "bd-panel-cards", role: "tabpanel", "aria-labelledby": "bd-tab-cards", className: "bd-tab-panel", hidden: props.activeTab !== 'cards', children: _jsxs(BdTabGrid, { children: [_jsx("section", { className: "bd-tile bd-tile-wide", children: _jsx(CardBehaviorSection, { bot: bot, putCardPref: putCardPref }) }), _jsx("section", { className: "bd-tile", children: _jsx(BrandSection, { bot: bot, patchBot: patchBot }) })] }) }), _jsx("div", { id: "bd-panel-advanced", role: "tabpanel", "aria-labelledby": "bd-tab-advanced", className: "bd-tab-panel", hidden: props.activeTab !== 'advanced', children: _jsxs(BdTabGrid, { children: [bot.cliId !== 'riff' ? (_jsx("section", { className: "bd-tile", children: _jsx(BackendTypeSection, { bot: bot, patchBot: patchBot }) })) : null, bot.cliId === 'codex-app' ? (_jsx("section", { className: "bd-tile", children: _jsx(CodexAppDisplaySection, { bot: bot, putCardPref: putCardPref }) })) : null, _jsx("section", { className: "bd-tile", children: _jsx(RuntimeEnvironmentSection, { bot: bot, patchBot: patchBot }) })] }) })] })] }));
|
|
445
|
+
return (_jsxs("article", { className: "bd-card bd-profile", "data-appid": bot.larkAppId, children: [_jsxs("div", { className: "bd-profile-chrome", children: [_jsxs("header", { className: "bd-profile-head", children: [_jsx(BotAvatarControl, { bot: bot, name: name, patchBot: patchBot }), _jsx("div", { className: "bd-profile-main", children: _jsx(BotProfileIdentity, { bot: bot, cli: cli, patchBot: patchBot, meta: (_jsxs(_Fragment, { children: [_jsxs("small", { className: "bd-meta-ok", children: ["\u25CF ", tr('botDefaults.metaOnline')] }), (def.since ?? 0) > 0 ? _jsxs("small", { "data-oncall-since": true, children: [tr('botDefaults.lastEnabled'), ": ", fmtSince(def.since ?? 0)] }) : null, (bot.autoboundChatCount ?? 0) > 0 ? _jsx("small", { children: tr('botDefaults.autobound', { count: bot.autoboundChatCount ?? 0 }) }) : null] })) }) })] }), _jsx(BotDefaultsTabs, { active: props.activeTab, onChange: props.onTabChange })] }), _jsxs("div", { className: "bd-body bd-tab-panels", children: [_jsx("div", { id: "bd-panel-common", role: "tabpanel", "aria-labelledby": "bd-tab-common", className: "bd-tab-panel", hidden: props.activeTab !== 'common', children: _jsxs(BdTabGrid, { children: [_jsx("section", { className: "bd-tile", children: _jsx(BotAgentSection, { bot: bot, sessionFallback: cli, cliState: cliState, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(WorkingDirSection, { bot: bot, patchBot: patchBot, putCardPref: putCardPref }) }), _jsx("section", { className: "bd-tile", children: _jsx(RoleSection, { bot: bot, patchBot: patchBot }) })] }) }), _jsx("div", { id: "bd-panel-sessions", role: "tabpanel", "aria-labelledby": "bd-tab-sessions", className: "bd-tab-panel", hidden: props.activeTab !== 'sessions', children: _jsxs(BdTabGrid, { children: [_jsx("section", { className: "bd-tile", children: _jsx(SessionModeSection, { bot: bot, patchBot: patchBot, putCardPref: putCardPref }) }), _jsx("section", { className: "bd-tile", children: _jsx(SubstituteModeSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(CrossBotSection, { bot: bot, putCardPref: putCardPref }) }), _jsx("section", { className: "bd-tile", children: _jsx(SessionCapSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(StartupCommandsSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(SummaryTriggerSection, { bot: bot, patchBot: patchBot, putCardPref: putCardPref }) })] }) }), _jsx("div", { id: "bd-panel-security", role: "tabpanel", "aria-labelledby": "bd-tab-security", className: "bd-tab-panel", hidden: props.activeTab !== 'security', children: _jsxs(BdTabGrid, { children: [bot.cliId !== 'riff' ? (_jsx("section", { className: "bd-tile", children: _jsx(SandboxSection, { bot: bot, patchBot: patchBot }) })) : null, bot.cliId !== 'riff' && bot.sandbox === true ? (_jsx("section", { className: "bd-tile bd-tile-wide", children: _jsx(SandboxPathsSection, { bot: bot, patchBot: patchBot }) })) : null, _jsx("section", { className: "bd-tile", children: _jsx(GrantSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(SlashCommandPermissionsSection, { bot: bot, patchBot: patchBot }) })] }) }), _jsx("div", { id: "bd-panel-cards", role: "tabpanel", "aria-labelledby": "bd-tab-cards", className: "bd-tab-panel", hidden: props.activeTab !== 'cards', children: _jsxs(BdTabGrid, { children: [_jsx("section", { className: "bd-tile bd-tile-wide", children: _jsx(CardBehaviorSection, { bot: bot, putCardPref: putCardPref }) }), _jsx("section", { className: "bd-tile bd-tile-wide", children: _jsx(FeedbackSettingsSection, { bot: bot, patchBot: patchBot }) }), _jsx("section", { className: "bd-tile", children: _jsx(BrandSection, { bot: bot, patchBot: patchBot }) })] }) }), _jsx("div", { id: "bd-panel-advanced", role: "tabpanel", "aria-labelledby": "bd-tab-advanced", className: "bd-tab-panel", hidden: props.activeTab !== 'advanced', children: _jsxs(BdTabGrid, { children: [bot.cliId !== 'riff' ? (_jsx("section", { className: "bd-tile", children: _jsx(BackendTypeSection, { bot: bot, patchBot: patchBot }) })) : null, bot.cliId === 'codex-app' ? (_jsx("section", { className: "bd-tile", children: _jsx(CodexAppDisplaySection, { bot: bot, putCardPref: putCardPref }) })) : null, bot.cliId === 'claude-code' ? (_jsx("section", { className: "bd-tile", children: _jsx(EnvelopeInjectionSection, { bot: bot, patchBot: patchBot }) })) : null, _jsx("section", { className: "bd-tile", children: _jsx(RuntimeEnvironmentSection, { bot: bot, patchBot: patchBot }) })] }) })] })] }));
|
|
446
|
+
}
|
|
447
|
+
function FeedbackSettingsSection(props) {
|
|
448
|
+
const enabled = props.bot.feedback?.enabled === true;
|
|
449
|
+
const [on, setOn] = useState(enabled);
|
|
450
|
+
const [json, setJson] = useState(JSON.stringify(props.bot.feedback ?? { enabled: true }, null, 2));
|
|
451
|
+
const [status, setStatus] = useState(null);
|
|
452
|
+
const [busy, setBusy] = useState(false);
|
|
453
|
+
const [chatId, setChatId] = useState('');
|
|
454
|
+
const [chats, setChats] = useState([]);
|
|
455
|
+
const [preview, setPreview] = useState(null);
|
|
456
|
+
useEffect(() => {
|
|
457
|
+
setOn(props.bot.feedback?.enabled === true);
|
|
458
|
+
setJson(JSON.stringify(props.bot.feedback ?? { enabled: true }, null, 2));
|
|
459
|
+
}, [props.bot.feedback]);
|
|
460
|
+
useEffect(() => {
|
|
461
|
+
void fetchGroupsSnapshot().then(snapshot => {
|
|
462
|
+
setChats(snapshot.chats.filter(chat => chat.memberBots.some(member => member.larkAppId === props.bot.larkAppId && member.inChat)));
|
|
463
|
+
}).catch(() => setChats([]));
|
|
464
|
+
}, [props.bot.larkAppId]);
|
|
465
|
+
async function save(nextOn = on) {
|
|
466
|
+
setBusy(true);
|
|
467
|
+
setStatus(null);
|
|
468
|
+
try {
|
|
469
|
+
let policy = { enabled: false };
|
|
470
|
+
if (nextOn) {
|
|
471
|
+
const parsed = JSON.parse(json);
|
|
472
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
473
|
+
throw new Error('高级 JSON 必须是对象');
|
|
474
|
+
policy = { ...parsed, enabled: true };
|
|
475
|
+
}
|
|
476
|
+
const res = await sendJson('PUT', `/api/bots/${encodeURIComponent(props.bot.larkAppId)}/feedback`, { feedback: JSON.stringify(policy) });
|
|
477
|
+
if (!res.ok)
|
|
478
|
+
throw new Error(responseErrorText(res));
|
|
479
|
+
props.patchBot(props.bot.larkAppId, { feedback: res.body.feedback ?? null });
|
|
480
|
+
setStatus({ text: '✓ 已保存', ok: true });
|
|
481
|
+
}
|
|
482
|
+
catch (e) {
|
|
483
|
+
setStatus({ text: `✗ ${caughtErrorText(e)}` });
|
|
484
|
+
}
|
|
485
|
+
finally {
|
|
486
|
+
setBusy(false);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
async function loadPreview() {
|
|
490
|
+
const q = chatId.trim() ? `?chatId=${encodeURIComponent(chatId.trim())}` : '';
|
|
491
|
+
const res = await fetch(`/api/bots/${encodeURIComponent(props.bot.larkAppId)}/feedback/effective${q}`);
|
|
492
|
+
const body = await res.json().catch(() => ({}));
|
|
493
|
+
if (!res.ok)
|
|
494
|
+
throw new Error(body?.error ?? `HTTP ${res.status}`);
|
|
495
|
+
setPreview(body.trace);
|
|
496
|
+
}
|
|
497
|
+
async function saveChat() {
|
|
498
|
+
if (!chatId.trim())
|
|
499
|
+
return setStatus({ text: '✗ 请输入聊天 ID' });
|
|
500
|
+
setBusy(true);
|
|
501
|
+
setStatus(null);
|
|
502
|
+
try {
|
|
503
|
+
const feedback = JSON.parse(json);
|
|
504
|
+
const res = await sendJson('PUT', `/api/bots/${encodeURIComponent(props.bot.larkAppId)}/chats/${encodeURIComponent(chatId.trim())}/feedback`, { feedback });
|
|
505
|
+
if (!res.ok)
|
|
506
|
+
throw new Error(responseErrorText(res));
|
|
507
|
+
await loadPreview();
|
|
508
|
+
setStatus({ text: '✓ 聊天覆盖已保存', ok: true });
|
|
509
|
+
}
|
|
510
|
+
catch (e) {
|
|
511
|
+
setStatus({ text: `✗ ${caughtErrorText(e)}` });
|
|
512
|
+
}
|
|
513
|
+
finally {
|
|
514
|
+
setBusy(false);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return (_jsxs("section", { className: "bd-section", "aria-busy": busy, children: [_jsx("h3", { className: "bd-section-title", children: "\u6700\u7EC8\u56DE\u7B54\u53CD\u9988" }), _jsx(ToggleRow, { checked: on, disabled: busy, title: "\u6700\u7EC8\u56DE\u7B54\u53CD\u9988", help: "\u9ED8\u8BA4\u5173\u95ED\uFF1B\u53EA\u5BF9\u8FD9\u4E2A bot \u7684\u6700\u7EC8\u56DE\u7B54\u751F\u6548", onChange: checked => { setOn(checked); void save(checked); } }), _jsxs("label", { className: "bd-row", children: [_jsx("span", { children: "\u9AD8\u7EA7 JSON" }), _jsx("textarea", { value: json, disabled: busy || !on, rows: 10, onChange: e => setJson(e.target.value) })] }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", className: "primary", disabled: busy || !on, onClick: () => void save(), children: "\u4FDD\u5B58\u53CD\u9988\u914D\u7F6E" }), _jsx(StatusSpan, { status: status })] }), _jsx("h4", { children: "\u6BCF\u804A\u5929\u8986\u76D6" }), _jsxs("label", { className: "bd-row", children: [_jsx("span", { children: "\u804A\u5929" }), _jsxs("select", { value: chatId, onChange: e => setChatId(e.target.value), children: [_jsx("option", { value: "", children: "\u9009\u62E9\u804A\u5929" }), chats.map(chat => _jsx("option", { value: chat.chatId, children: chat.name || chat.chatId }, chat.chatId))] })] }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", disabled: busy || !chatId.trim(), onClick: () => void saveChat(), children: "\u4FDD\u5B58\u804A\u5929\u8986\u76D6" }), _jsx("button", { type: "button", disabled: busy, onClick: () => void loadPreview(), children: "\u751F\u6548\u9884\u89C8" })] }), preview ? _jsx("pre", { className: "code-block", children: JSON.stringify(preview, null, 2) }) : null] }));
|
|
444
518
|
}
|
|
445
519
|
function RuntimeEnvironmentSection(props) {
|
|
446
520
|
const tr = useT();
|
|
@@ -734,6 +808,14 @@ export function BotAgentSection(props) {
|
|
|
734
808
|
const [cliKey, setCliKey] = useState(initialKey);
|
|
735
809
|
const [cliSelectionTouched, setCliSelectionTouched] = useState(false);
|
|
736
810
|
const [model, setModel] = useState(typeof bot.model === 'string' ? bot.model : '');
|
|
811
|
+
const [reasoningEffort, setReasoningEffort] = useState(bot.reasoningEffort ?? '');
|
|
812
|
+
// dsh-only turn timeout, edited in minutes (bots.json stores ms). Empty = use
|
|
813
|
+
// the runner default (10 min). `touched` gates whether a save sends the field
|
|
814
|
+
// at all: an untouched field is omitted so the daemon preserves the exact
|
|
815
|
+
// stored ms (including legal non-whole-minute values) instead of clearing it.
|
|
816
|
+
const [turnTimeoutMin, setTurnTimeoutMin] = useState(turnTimeoutMinFromMs(bot.turnTimeoutMs));
|
|
817
|
+
const [turnTimeoutTouched, setTurnTimeoutTouched] = useState(false);
|
|
818
|
+
const [turnTimeoutError, setTurnTimeoutError] = useState(null);
|
|
737
819
|
const [runtimeDraft, setRuntimeDraft] = useState(() => runtimeDraftFromBot(bot));
|
|
738
820
|
const [runtimeTouched, setRuntimeTouched] = useState(false);
|
|
739
821
|
const [runtimeStatus, setRuntimeStatus] = useState(null);
|
|
@@ -746,6 +828,10 @@ export function BotAgentSection(props) {
|
|
|
746
828
|
setCliKey(agentSelectionKey(bot, props.sessionFallback));
|
|
747
829
|
setCliSelectionTouched(false);
|
|
748
830
|
setModel(typeof bot.model === 'string' ? bot.model : '');
|
|
831
|
+
setReasoningEffort(bot.reasoningEffort ?? '');
|
|
832
|
+
setTurnTimeoutMin(turnTimeoutMinFromMs(bot.turnTimeoutMs));
|
|
833
|
+
setTurnTimeoutTouched(false);
|
|
834
|
+
setTurnTimeoutError(null);
|
|
749
835
|
setRuntimeDraft(runtimeDraftFromBot(bot));
|
|
750
836
|
setRuntimeTouched(false);
|
|
751
837
|
setSkillValue(skillInjectionResolved(bot));
|
|
@@ -754,6 +840,8 @@ export function BotAgentSection(props) {
|
|
|
754
840
|
bot.cliId,
|
|
755
841
|
bot.larkAppId,
|
|
756
842
|
bot.model,
|
|
843
|
+
bot.reasoningEffort,
|
|
844
|
+
bot.turnTimeoutMs,
|
|
757
845
|
runtimeConfigKey,
|
|
758
846
|
bot.wrapperCli,
|
|
759
847
|
bot.skillInjection,
|
|
@@ -836,11 +924,32 @@ export function BotAgentSection(props) {
|
|
|
836
924
|
: { provider: runtimeDraft.updateProvider },
|
|
837
925
|
};
|
|
838
926
|
}
|
|
927
|
+
// dsh-only turn timeout: validate the (touched) minutes input before saving
|
|
928
|
+
// so an illegal value surfaces an inline error instead of silently clearing
|
|
929
|
+
// the config. Untouched → omitted below so the daemon preserves the stored
|
|
930
|
+
// ms exactly (including legal non-whole-minute values).
|
|
931
|
+
let turnTimeoutField;
|
|
932
|
+
if (cliKey === 'dsh' && turnTimeoutTouched) {
|
|
933
|
+
const parsed = parseTurnTimeoutMinInput(turnTimeoutMin);
|
|
934
|
+
if (parsed === 'invalid') {
|
|
935
|
+
const text = tr('botDefaults.agentTurnTimeoutInvalid');
|
|
936
|
+
setTurnTimeoutError(text);
|
|
937
|
+
setAgentStatus({ text: `✗ ${text}` });
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
setTurnTimeoutError(null);
|
|
941
|
+
turnTimeoutField = parsed; // number (minutes→ms) or '' (clear)
|
|
942
|
+
}
|
|
839
943
|
setAgentBusy(true);
|
|
840
944
|
try {
|
|
841
945
|
const body = {
|
|
842
946
|
cliId: cliKey,
|
|
843
947
|
model,
|
|
948
|
+
reasoningEffort: (cliKey === 'codex' || cliKey === 'codex-app' || cliKey.endsWith('-codex')) ? reasoningEffort : '',
|
|
949
|
+
// dsh-only: only send when the user actually edited the field. Omitting
|
|
950
|
+
// it makes the daemon preserve the current value; non-dsh selections
|
|
951
|
+
// never send it (the daemon drops any stored value for non-dsh CLIs).
|
|
952
|
+
...(cliKey === 'dsh' && turnTimeoutField !== undefined ? { turnTimeoutMs: turnTimeoutField } : {}),
|
|
844
953
|
...(runtimeTouched ? { cliRuntime } : {}),
|
|
845
954
|
};
|
|
846
955
|
const res = await sendJson('PUT', `/api/bots/${encodeURIComponent(bot.larkAppId)}/agent`, body);
|
|
@@ -864,8 +973,15 @@ export function BotAgentSection(props) {
|
|
|
864
973
|
: res.body.cliPathOverride,
|
|
865
974
|
wrapperCli: res.body.wrapperCli ?? null,
|
|
866
975
|
model: res.body.model ?? '',
|
|
976
|
+
reasoningEffort: res.body.reasoningEffort ?? undefined,
|
|
977
|
+
turnTimeoutMs: typeof res.body.turnTimeoutMs === 'number' ? res.body.turnTimeoutMs : undefined,
|
|
867
978
|
agentSelectionKey: res.body.selectionKey ?? cliKey,
|
|
868
979
|
});
|
|
980
|
+
// Re-sync the minutes input from the authoritative saved ms and clear
|
|
981
|
+
// the dirty flag so a subsequent unrelated save won't touch the field.
|
|
982
|
+
setTurnTimeoutMin(turnTimeoutMinFromMs(typeof res.body.turnTimeoutMs === 'number' ? res.body.turnTimeoutMs : undefined));
|
|
983
|
+
setTurnTimeoutTouched(false);
|
|
984
|
+
setTurnTimeoutError(null);
|
|
869
985
|
setRuntimeTouched(false);
|
|
870
986
|
if (cliRuntime) {
|
|
871
987
|
const probe = res.body.runtimeProbe;
|
|
@@ -956,6 +1072,14 @@ export function BotAgentSection(props) {
|
|
|
956
1072
|
}
|
|
957
1073
|
const siSupport = bot.skillInjectionSupport === 'dynamic' ? 'dynamic' : bot.skillInjectionSupport === 'global' ? 'global' : 'none';
|
|
958
1074
|
const isRiff = cliKey === 'riff';
|
|
1075
|
+
const isCodexSelection = cliKey === 'codex' || cliKey === 'codex-app' || cliKey.endsWith('-codex');
|
|
1076
|
+
// The dsh adapter is the only one that forwards a runner turn timeout.
|
|
1077
|
+
const isDsh = cliKey === 'dsh';
|
|
1078
|
+
const reasoningEffortOptions = useMemo(() => codexReasoningEffortsForModel(model), [model]);
|
|
1079
|
+
useEffect(() => {
|
|
1080
|
+
if (reasoningEffort && !reasoningEffortOptions.includes(reasoningEffort))
|
|
1081
|
+
setReasoningEffort('');
|
|
1082
|
+
}, [reasoningEffort, reasoningEffortOptions]);
|
|
959
1083
|
// Old dashboard payloads can omit agentSelectionKey while still carrying a
|
|
960
1084
|
// legacy wrapperCli. Keep the custom-runtime editor hidden until the user
|
|
961
1085
|
// explicitly selects bare Codex; structured runtimes and wrappers cannot mix.
|
|
@@ -990,7 +1114,69 @@ export function BotAgentSection(props) {
|
|
|
990
1114
|
? 'botDefaults.runtimeOfficialNote'
|
|
991
1115
|
: runtimeDraft.mode === 'legacy'
|
|
992
1116
|
? 'botDefaults.runtimeLegacyNote'
|
|
993
|
-
: 'botDefaults.runtimeCustomNote') }), runtimeDraft.mode === 'legacy' ? (_jsx("div", { className: "bd-runtime-fields", "data-runtime-legacy": "", children: _jsxs("label", { className: "bd-runtime-wide", children: [_jsx("span", { children: tr('botDefaults.runtimeLegacyPath') }), _jsx("input", { type: "text", value: runtimeDraft.legacyPath, readOnly: true, "aria-readonly": "true", "data-input": "agentRuntimeLegacyPath" })] }) })) : null, runtimeDraft.mode === 'custom' ? (_jsxs("div", { className: "bd-runtime-fields", children: [_jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.runtimeIdHelp'), children: tr('botDefaults.runtimeId') }), _jsx("input", { type: "text", "data-input": "agentRuntimeId", value: runtimeDraft.id, disabled: agentBusy, autoComplete: "off", onChange: event => updateRuntimeDraft({ id: event.currentTarget.value }) })] }), _jsxs("label", { children: [_jsx("span", { children: tr('botDefaults.runtimeDisplayName') }), _jsx("input", { type: "text", "data-input": "agentRuntimeDisplayName", placeholder: tr('botDefaults.runtimeDisplayNamePlaceholder'), value: runtimeDraft.displayName, disabled: agentBusy, autoComplete: "off", onChange: event => updateRuntimeDraft({ displayName: event.currentTarget.value }) })] }), _jsxs("label", { className: "bd-runtime-wide", children: [_jsx(FieldTitle, { help: tr('botDefaults.runtimeExecutableHelp'), children: tr('botDefaults.runtimeExecutable') }), _jsx("input", { type: "text", "data-input": "agentRuntimeExecutable", value: runtimeDraft.executable, disabled: agentBusy, autoCapitalize: "none", autoComplete: "off", spellCheck: false, onChange: event => updateRuntimeDraft({ executable: event.currentTarget.value }) })] }), _jsxs("div", { className: "bd-field", children: [_jsx("span", { children: tr('botDefaults.runtimeUpdateProvider') }), _jsx(DropdownField, { dataInput: "agentRuntimeUpdateProvider", ariaLabel: tr('botDefaults.runtimeUpdateProvider'), value: runtimeDraft.updateProvider, disabled: agentBusy, options: runtimeProviderOptions, onChange: updateProvider => updateRuntimeDraft({ updateProvider }) })] }), runtimeDraft.updateProvider === 'npm' ? (_jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.runtimePackageHelp'), children: tr('botDefaults.runtimePackageName') }), _jsx("input", { type: "text", "data-input": "agentRuntimePackageName", value: runtimeDraft.packageName, disabled: agentBusy, autoCapitalize: "none", autoComplete: "off", spellCheck: false, onChange: event => updateRuntimeDraft({ packageName: event.currentTarget.value }) })] })) : null] })) : null, _jsx(StatusSpan, { status: runtimeStatus, attr: { 'data-runtime-status': '' } })] })) : null, !isRiff && (_jsx("div", { className: "bd-row", children: _jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.agentHelp'), children: tr('botDefaults.agentModel') }), _jsx("input", { type: "text", "data-input": "agentModel", list: `agent-model-suggestions-${bot.larkAppId}`, placeholder: modelPlaceholder, value: model, disabled: agentBusy || modelDisabledByCli, onChange: event => setModel(event.currentTarget.value) }), _jsx("datalist", { id: `agent-model-suggestions-${bot.larkAppId}`, children: suggestions.map(item => _jsx("option", { value: item }, item)) })] }) })),
|
|
1117
|
+
: 'botDefaults.runtimeCustomNote') }), runtimeDraft.mode === 'legacy' ? (_jsx("div", { className: "bd-runtime-fields", "data-runtime-legacy": "", children: _jsxs("label", { className: "bd-runtime-wide", children: [_jsx("span", { children: tr('botDefaults.runtimeLegacyPath') }), _jsx("input", { type: "text", value: runtimeDraft.legacyPath, readOnly: true, "aria-readonly": "true", "data-input": "agentRuntimeLegacyPath" })] }) })) : null, runtimeDraft.mode === 'custom' ? (_jsxs("div", { className: "bd-runtime-fields", children: [_jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.runtimeIdHelp'), children: tr('botDefaults.runtimeId') }), _jsx("input", { type: "text", "data-input": "agentRuntimeId", value: runtimeDraft.id, disabled: agentBusy, autoComplete: "off", onChange: event => updateRuntimeDraft({ id: event.currentTarget.value }) })] }), _jsxs("label", { children: [_jsx("span", { children: tr('botDefaults.runtimeDisplayName') }), _jsx("input", { type: "text", "data-input": "agentRuntimeDisplayName", placeholder: tr('botDefaults.runtimeDisplayNamePlaceholder'), value: runtimeDraft.displayName, disabled: agentBusy, autoComplete: "off", onChange: event => updateRuntimeDraft({ displayName: event.currentTarget.value }) })] }), _jsxs("label", { className: "bd-runtime-wide", children: [_jsx(FieldTitle, { help: tr('botDefaults.runtimeExecutableHelp'), children: tr('botDefaults.runtimeExecutable') }), _jsx("input", { type: "text", "data-input": "agentRuntimeExecutable", value: runtimeDraft.executable, disabled: agentBusy, autoCapitalize: "none", autoComplete: "off", spellCheck: false, onChange: event => updateRuntimeDraft({ executable: event.currentTarget.value }) })] }), _jsxs("div", { className: "bd-field", children: [_jsx("span", { children: tr('botDefaults.runtimeUpdateProvider') }), _jsx(DropdownField, { dataInput: "agentRuntimeUpdateProvider", ariaLabel: tr('botDefaults.runtimeUpdateProvider'), value: runtimeDraft.updateProvider, disabled: agentBusy, options: runtimeProviderOptions, onChange: updateProvider => updateRuntimeDraft({ updateProvider }) })] }), runtimeDraft.updateProvider === 'npm' ? (_jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.runtimePackageHelp'), children: tr('botDefaults.runtimePackageName') }), _jsx("input", { type: "text", "data-input": "agentRuntimePackageName", value: runtimeDraft.packageName, disabled: agentBusy, autoCapitalize: "none", autoComplete: "off", spellCheck: false, onChange: event => updateRuntimeDraft({ packageName: event.currentTarget.value }) })] })) : null] })) : null, _jsx(StatusSpan, { status: runtimeStatus, attr: { 'data-runtime-status': '' } })] })) : null, !isRiff && (_jsx("div", { className: "bd-row", children: _jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.agentHelp'), children: tr('botDefaults.agentModel') }), _jsx("input", { type: "text", "data-input": "agentModel", list: `agent-model-suggestions-${bot.larkAppId}`, placeholder: modelPlaceholder, value: model, disabled: agentBusy || modelDisabledByCli, onChange: event => setModel(event.currentTarget.value) }), _jsx("datalist", { id: `agent-model-suggestions-${bot.larkAppId}`, children: suggestions.map(item => _jsx("option", { value: item }, item)) })] }) })), isDsh && (_jsx("div", { className: "bd-row", children: _jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.agentTurnTimeoutHelp'), children: tr('botDefaults.agentTurnTimeout') }), _jsx("input", { type: "number", min: 0,
|
|
1118
|
+
// Allow non-whole minutes so a legal non-60000-multiple ms value
|
|
1119
|
+
// (e.g. 90001ms ≈ 1.50002min) can be shown and edited losslessly.
|
|
1120
|
+
step: "any", inputMode: "decimal", "data-input": "agentTurnTimeout", placeholder: tr('botDefaults.agentTurnTimeoutPlaceholder'), value: turnTimeoutMin, disabled: agentBusy, onChange: event => {
|
|
1121
|
+
setTurnTimeoutMin(event.currentTarget.value);
|
|
1122
|
+
setTurnTimeoutTouched(true);
|
|
1123
|
+
setTurnTimeoutError(null);
|
|
1124
|
+
} }), turnTimeoutError ? _jsx("small", { className: "hint-warn", "data-turn-timeout-error": "", children: turnTimeoutError }) : null] }) })), isCodexSelection && (_jsx("div", { className: "bd-row", children: _jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.agentReasoningEffortHelp'), children: tr('botDefaults.agentReasoningEffort') }), _jsx(DropdownField, { dataInput: "agentReasoningEffort", ariaLabel: tr('botDefaults.agentReasoningEffort'), value: reasoningEffort, disabled: agentBusy, options: [
|
|
1125
|
+
{ value: '', label: tr('botDefaults.agentReasoningEffortDefault') },
|
|
1126
|
+
...reasoningEffortOptions.map(value => ({
|
|
1127
|
+
value,
|
|
1128
|
+
label: tr(`botDefaults.agentReasoningEffort${value === 'xhigh' ? 'Xhigh' : value[0].toUpperCase() + value.slice(1)}`),
|
|
1129
|
+
})),
|
|
1130
|
+
], onChange: next => setReasoningEffort(next) })] }) })), isRiff && _jsx(RiffSection, { bot: bot, patchBot: patchBot, persistCliSelection: persistRiffCliSelection }), !isRiff && siSupport === 'dynamic' ? (_jsx("div", { className: "bd-row", children: _jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.skillInjectionHelpDynamic'), children: tr('botDefaults.skillInjection') }), _jsx(DropdownField, { dataInput: "skillInjection", ariaLabel: tr('botDefaults.skillInjection'), value: "dynamic", disabled: true, options: dynamicSkillOptions, onChange: () => undefined })] }) })) : !isRiff && siSupport === 'global' ? (_jsxs("div", { className: "bd-row", children: [_jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.skillInjectionHelp'), children: tr('botDefaults.skillInjection') }), _jsx(DropdownField, { dataInput: "skillInjection", ariaLabel: tr('botDefaults.skillInjection'), value: skillValue, disabled: skillBusy, options: skillOptions, onChange: next => void saveSkillInjection(next) })] }), _jsx("div", { className: "actions", children: _jsx(StatusSpan, { status: skillStatus, attr: { 'data-skill-injection-status': '' } }) })] })) : null, !isRiff && (_jsxs("div", { className: "actions bd-section-actions", children: [_jsx("button", { type: "button", className: "primary", "data-action": "save-agent", disabled: agentBusy, onClick: () => void saveAgent(), children: tr('botDefaults.agentSave') }), _jsx(StatusSpan, { status: agentStatus, attr: { 'data-agent-status': '' } })] }))] }));
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Node's setTimeout delay caps at a 32-bit signed int of ms; a larger value
|
|
1134
|
+
* wraps to ~1ms. Kept in lockstep with `MAX_TURN_TIMEOUT_MS` in bot-registry
|
|
1135
|
+
* (a browser bundle can't import that Node-side module); a unit test asserts the
|
|
1136
|
+
* two stay equal so this copy can't silently drift.
|
|
1137
|
+
*/
|
|
1138
|
+
export const DASHBOARD_MAX_TURN_TIMEOUT_MS = 2_147_483_647;
|
|
1139
|
+
/**
|
|
1140
|
+
* Convert a stored dsh turn timeout (ms) into the minutes string shown in the
|
|
1141
|
+
* input. Absent / non-positive / non-integer / over-bound → empty (the field
|
|
1142
|
+
* then means "use the runner default"). A legal value that is not a whole
|
|
1143
|
+
* number of minutes is shown as its decimal minutes (trimmed of any float
|
|
1144
|
+
* tail) rather than hidden as empty; `parseTurnTimeoutMinInput` re-rounds it to
|
|
1145
|
+
* the nearest whole ms, so the displayed value round-trips back to the same ms.
|
|
1146
|
+
*/
|
|
1147
|
+
function turnTimeoutMinFromMs(ms) {
|
|
1148
|
+
if (typeof ms !== 'number' || !Number.isInteger(ms) || ms <= 0 || ms > DASHBOARD_MAX_TURN_TIMEOUT_MS)
|
|
1149
|
+
return '';
|
|
1150
|
+
const minutes = ms / 60_000;
|
|
1151
|
+
// Trim any floating-point tail; parseTurnTimeoutMinInput re-rounds to ms.
|
|
1152
|
+
return Number.isInteger(minutes) ? String(minutes) : String(Number(minutes.toFixed(10)));
|
|
1153
|
+
}
|
|
1154
|
+
/**
|
|
1155
|
+
* Parse the minutes input for the PUT body. Returns:
|
|
1156
|
+
* - `''` → cleared (empty input) → daemon reverts to the runner default,
|
|
1157
|
+
* - a number → minutes → ms, rounded to the nearest whole ms, a positive
|
|
1158
|
+
* integer within the arm-able bound,
|
|
1159
|
+
* - `'invalid'` → the operator typed something that is not a clearable blank
|
|
1160
|
+
* and not a representable positive timeout (0, negative, NaN,
|
|
1161
|
+
* or a minutes value whose nearest ms is ≤0 / over-bound).
|
|
1162
|
+
* Rounding to the nearest whole ms makes the value shown by
|
|
1163
|
+
* `turnTimeoutMinFromMs` (a possibly-decimal minutes figure) round-trip back to
|
|
1164
|
+
* the exact stored ms; invalid input is surfaced inline, never silently cleared.
|
|
1165
|
+
*/
|
|
1166
|
+
function parseTurnTimeoutMinInput(minutes) {
|
|
1167
|
+
const trimmed = minutes.trim();
|
|
1168
|
+
if (!trimmed)
|
|
1169
|
+
return '';
|
|
1170
|
+
const asMinutes = Number(trimmed);
|
|
1171
|
+
if (!Number.isFinite(asMinutes) || asMinutes <= 0)
|
|
1172
|
+
return 'invalid';
|
|
1173
|
+
// Round to the nearest whole ms: the minutes field is a lossy display of a
|
|
1174
|
+
// ms value, so snapping back to an integer ms is the safe, non-destructive
|
|
1175
|
+
// interpretation (e.g. 1.5000166667 min → 90001 ms).
|
|
1176
|
+
const ms = Math.round(asMinutes * 60_000);
|
|
1177
|
+
if (ms <= 0 || ms > DASHBOARD_MAX_TURN_TIMEOUT_MS)
|
|
1178
|
+
return 'invalid';
|
|
1179
|
+
return ms;
|
|
994
1180
|
}
|
|
995
1181
|
function skillInjectionResolved(bot) {
|
|
996
1182
|
const override = bot.skillInjection === 'global' || bot.skillInjection === 'prompt' || bot.skillInjection === 'off' ? bot.skillInjection : '';
|
|
@@ -1635,6 +1821,40 @@ export function CodexAppDisplaySection(props) {
|
|
|
1635
1821
|
}
|
|
1636
1822
|
return (_jsxs("section", { className: "bd-section", "data-codex-app-display": true, children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionCodexAppDisplay') }), _jsx(ToggleRow, { checked: cleanInput, disabled: busy, dataAction: "toggle-codex-app-clean-input", title: tr('botDefaults.codexAppCleanInput'), help: tr('botDefaults.codexAppCleanInputHelp'), onChange: checked => void save(checked) }), _jsx("small", { className: "bd-section-note", children: tr('botDefaults.codexAppCleanInputCompat') }), _jsx("div", { className: "actions", children: _jsx(StatusSpan, { status: status, attr: { 'data-codex-app-clean-input-status': '' } }) })] }));
|
|
1637
1823
|
}
|
|
1824
|
+
export function EnvelopeInjectionSection(props) {
|
|
1825
|
+
const tr = useT();
|
|
1826
|
+
const [auto, setAuto] = useState(props.bot.envelopeInjection === 'auto');
|
|
1827
|
+
const [status, setStatus] = useState(null);
|
|
1828
|
+
const [busy, setBusy] = useState(false);
|
|
1829
|
+
useEffect(() => setAuto(props.bot.envelopeInjection === 'auto'), [props.bot.envelopeInjection]);
|
|
1830
|
+
async function save(next) {
|
|
1831
|
+
const previous = auto;
|
|
1832
|
+
setAuto(next);
|
|
1833
|
+
setBusy(true);
|
|
1834
|
+
setStatus(null);
|
|
1835
|
+
try {
|
|
1836
|
+
const res = await sendJson('PUT', `/api/bots/${encodeURIComponent(props.bot.larkAppId)}/envelope-injection`, { envelopeInjection: next ? 'auto' : 'off' });
|
|
1837
|
+
if (res.ok && res.body.ok) {
|
|
1838
|
+
const saved = res.body.envelopeInjection === 'auto';
|
|
1839
|
+
setAuto(saved);
|
|
1840
|
+
props.patchBot(props.bot.larkAppId, { envelopeInjection: saved ? 'auto' : 'off' });
|
|
1841
|
+
setStatus({ text: `✓ ${tr('botDefaults.cardPrefSaved')}`, ok: true });
|
|
1842
|
+
}
|
|
1843
|
+
else {
|
|
1844
|
+
setAuto(previous);
|
|
1845
|
+
setStatus({ text: `✗ ${responseErrorText(res)}` });
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
catch (e) {
|
|
1849
|
+
setAuto(previous);
|
|
1850
|
+
setStatus({ text: `✗ ${caughtErrorText(e)}` });
|
|
1851
|
+
}
|
|
1852
|
+
finally {
|
|
1853
|
+
setBusy(false);
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
return (_jsxs("section", { className: "bd-section", "data-envelope-injection": true, children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.envelopeInjection') }), _jsx(ToggleRow, { checked: auto, disabled: busy, dataAction: "toggle-envelope-injection", title: tr('botDefaults.envelopeInjectionAuto'), help: tr('botDefaults.envelopeInjectionHelp'), onChange: checked => void save(checked) }), _jsx("small", { className: "bd-section-note", children: tr('botDefaults.envelopeInjectionNote') }), _jsx("div", { className: "actions", children: _jsx(StatusSpan, { status: status, attr: { 'data-envelope-injection-status': '' } }) })] }));
|
|
1857
|
+
}
|
|
1638
1858
|
function CrossBotSection(props) {
|
|
1639
1859
|
const tr = useT();
|
|
1640
1860
|
const [sameDir, setSameDir] = useState(props.bot.botToBotSameDir !== false);
|
|
@@ -1760,7 +1980,7 @@ function summaryRange(bot) {
|
|
|
1760
1980
|
}
|
|
1761
1981
|
function SessionModeSection(props) {
|
|
1762
1982
|
const tr = useT();
|
|
1763
|
-
const [p2p, setP2p] = useState(props.bot.p2pMode
|
|
1983
|
+
const [p2p, setP2p] = useState(normalizeP2pMode(props.bot.p2pMode));
|
|
1764
1984
|
const [regular, setRegular] = useState(regularGroupMode(props.bot));
|
|
1765
1985
|
const [mention, setMention] = useState(mentionMode(props.bot));
|
|
1766
1986
|
const [docMode, setDocMode] = useState(props.bot.docSubscribeDefaultMode === 'all' ? 'all' : 'mention-only');
|
|
@@ -1770,7 +1990,7 @@ function SessionModeSection(props) {
|
|
|
1770
1990
|
const [mentionStatus, setMentionStatus] = useState(null);
|
|
1771
1991
|
const [docStatus, setDocStatus] = useState(null);
|
|
1772
1992
|
useEffect(() => {
|
|
1773
|
-
setP2p(props.bot.p2pMode
|
|
1993
|
+
setP2p(normalizeP2pMode(props.bot.p2pMode));
|
|
1774
1994
|
setRegular(regularGroupMode(props.bot));
|
|
1775
1995
|
setMention(mentionMode(props.bot));
|
|
1776
1996
|
setDocMode(props.bot.docSubscribeDefaultMode === 'all' ? 'all' : 'mention-only');
|
|
@@ -1781,14 +2001,14 @@ function SessionModeSection(props) {
|
|
|
1781
2001
|
props.bot.regularGroupReplyMode,
|
|
1782
2002
|
]);
|
|
1783
2003
|
async function saveP2p(next) {
|
|
1784
|
-
const mode = next
|
|
2004
|
+
const mode = normalizeP2pMode(next);
|
|
1785
2005
|
setP2p(mode);
|
|
1786
2006
|
setBusy('p2p');
|
|
1787
2007
|
setP2pStatus(null);
|
|
1788
2008
|
try {
|
|
1789
2009
|
const res = await sendJson('PUT', `/api/bots/${encodeURIComponent(props.bot.larkAppId)}/p2p-mode`, { p2pMode: mode });
|
|
1790
2010
|
if (res.ok && res.body.ok) {
|
|
1791
|
-
props.patchBot(props.bot.larkAppId, { p2pMode: res.body.p2pMode
|
|
2011
|
+
props.patchBot(props.bot.larkAppId, { p2pMode: normalizeP2pMode(res.body.p2pMode) });
|
|
1792
2012
|
setP2pStatus({ text: `✓ ${tr('botDefaults.cardPrefSaved')}`, ok: true });
|
|
1793
2013
|
}
|
|
1794
2014
|
else {
|
|
@@ -1819,6 +2039,7 @@ function SessionModeSection(props) {
|
|
|
1819
2039
|
const p2pOptions = [
|
|
1820
2040
|
{ value: 'thread', label: tr('botDefaults.p2pThread') },
|
|
1821
2041
|
{ value: 'chat', label: tr('botDefaults.p2pChat') },
|
|
2042
|
+
{ value: 'group', label: tr('botDefaults.p2pGroup') },
|
|
1822
2043
|
];
|
|
1823
2044
|
const regularOptions = [
|
|
1824
2045
|
{ value: 'chat', label: tr('botDefaults.regularGroupModeChat') },
|
|
@@ -1836,7 +2057,7 @@ function SessionModeSection(props) {
|
|
|
1836
2057
|
{ value: 'mention-only', label: tr('botDefaults.docSubscribeModeMention') },
|
|
1837
2058
|
{ value: 'all', label: tr('botDefaults.docSubscribeModeAll') },
|
|
1838
2059
|
];
|
|
1839
|
-
return (_jsxs("section", { className: "bd-section", children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionSessionMode') }), _jsxs("div", { className: "bd-row", children: [_jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.p2pHelp'), children: tr('botDefaults.p2pMode') }), _jsx(DropdownField, { dataInput: "p2pMode", ariaLabel: tr('botDefaults.p2pMode'), value: p2p, disabled: busy === 'p2p', options: p2pOptions, onChange: next => void saveP2p(next) })] }), _jsx("div", { className: "actions", children: _jsx(StatusSpan, { status: p2pStatus, attr: { 'data-p2p-status': '' } }) })] }), _jsxs("div", { className: "bd-row", children: [_jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.regularGroupModeHelp'), children: tr('botDefaults.regularGroupMode') }), _jsx(DropdownField, { dataInput: "regularGroupMode", ariaLabel: tr('botDefaults.regularGroupMode'), value: regular, disabled: busy === 'regular', options: regularOptions, onChange: next => {
|
|
2060
|
+
return (_jsxs("section", { className: "bd-section", children: [_jsx("h3", { className: "bd-section-title", children: tr('botDefaults.sectionSessionMode') }), _jsxs("div", { className: "bd-row", children: [_jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.p2pHelp'), children: tr('botDefaults.p2pMode') }), _jsx(DropdownField, { dataInput: "p2pMode", ariaLabel: tr('botDefaults.p2pMode'), value: p2p, disabled: busy === 'p2p', options: p2pOptions, onChange: next => void saveP2p(next) })] }), _jsx("div", { className: "actions", children: _jsx(StatusSpan, { status: p2pStatus, attr: { 'data-p2p-status': '' } }) })] }), p2p === 'group' && _jsx(SessionGroupTagRow, { bot: props.bot }), _jsxs("div", { className: "bd-row", children: [_jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.regularGroupModeHelp'), children: tr('botDefaults.regularGroupMode') }), _jsx(DropdownField, { dataInput: "regularGroupMode", ariaLabel: tr('botDefaults.regularGroupMode'), value: regular, disabled: busy === 'regular', options: regularOptions, onChange: next => {
|
|
1840
2061
|
setRegular(next);
|
|
1841
2062
|
void saveCardMode('regular', { regularGroupReplyMode: next }, setRegularStatus);
|
|
1842
2063
|
} })] }), _jsx("div", { className: "actions", children: _jsx(StatusSpan, { status: regularStatus, attr: { 'data-regular-group-status': '' } }) })] }), _jsxs("div", { className: "bd-row", children: [_jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.mentionModeHelp'), children: tr('botDefaults.mentionMode') }), _jsx(DropdownField, { dataInput: "regularGroupMentionMode", ariaLabel: tr('botDefaults.mentionMode'), value: mention, disabled: busy === 'mention', options: mentionOptions, onChange: next => {
|
|
@@ -2103,6 +2324,88 @@ function SubstituteModeSection(props) {
|
|
|
2103
2324
|
});
|
|
2104
2325
|
}, children: _jsx("span", { "aria-hidden": "true", children: "\u00D7" }) })] }, target.key))), _jsx("button", { type: "button", className: "bd-substitute-target-add", "data-action": "add-substitute-target", title: tr('botDefaults.substituteTargetAdd'), "aria-label": tr('botDefaults.substituteTargetAdd'), disabled: busy, onClick: () => setTargetRows(rows => [...rows, makeTargetDraft()]), children: _jsx("span", { "aria-hidden": "true", children: "+" }) })] })] }), _jsxs("div", { className: "actions", children: [_jsx("button", { type: "button", className: "primary", "data-action": "save-substitute-mode", disabled: busy, onClick: saveCurrent, children: tr('botDefaults.substituteSave') }), _jsx("button", { type: "button", "data-action": "off-substitute-mode", disabled: busy, onClick: () => void save({ enabled: false, targets: [] }), children: tr('botDefaults.substituteOff') }), _jsx(StatusSpan, { status: status, attr: { 'data-substitute-status': '' } })] })] }));
|
|
2105
2326
|
}
|
|
2327
|
+
function normalizeP2pMode(value) {
|
|
2328
|
+
return value === 'thread' ? 'thread' : value === 'group' ? 'group' : 'chat';
|
|
2329
|
+
}
|
|
2330
|
+
/** 会话群标签行(p2pMode=group 时显示):tag mode 选择器 + 按模式分支的
|
|
2331
|
+
* 授权 UI(PR review:授权行必须与实际 tagMode 一致)。
|
|
2332
|
+
* - feed-group(默认):个人侧边栏分组,需一次 OAuth → 显示状态徽标 + 一键授权
|
|
2333
|
+
* - chat-tag:应用租户身份打企业群标签,无需用户授权(部分租户权限目录无该
|
|
2334
|
+
* scope)→ 不显示授权按钮
|
|
2335
|
+
* - off:不打标签
|
|
2336
|
+
* 一键授权 → 新标签页打开飞书授权 → 回跳 dashboard /oauth/callback 自动完成
|
|
2337
|
+
* → 本行轮询到 authorized 后徽标变绿。 */
|
|
2338
|
+
function SessionGroupTagRow(props) {
|
|
2339
|
+
const tr = useT();
|
|
2340
|
+
const [status, setStatus] = useState(null);
|
|
2341
|
+
const [authBusy, setAuthBusy] = useState(false);
|
|
2342
|
+
const [modeBusy, setModeBusy] = useState(false);
|
|
2343
|
+
const [err, setErr] = useState(null);
|
|
2344
|
+
const fetchStatus = async () => {
|
|
2345
|
+
try {
|
|
2346
|
+
const res = await sendJson('GET', `/api/bots/${encodeURIComponent(props.bot.larkAppId)}/session-group-tag-status`);
|
|
2347
|
+
if (res.ok && res.body.ok) {
|
|
2348
|
+
setStatus({ authorized: !!res.body.authorized, tagMode: String(res.body.tagMode ?? 'feed-group') });
|
|
2349
|
+
return !!res.body.authorized;
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
catch { /* transient */ }
|
|
2353
|
+
return false;
|
|
2354
|
+
};
|
|
2355
|
+
useEffect(() => { void fetchStatus(); }, [props.bot.larkAppId]);
|
|
2356
|
+
async function saveMode(next) {
|
|
2357
|
+
setModeBusy(true);
|
|
2358
|
+
setErr(null);
|
|
2359
|
+
try {
|
|
2360
|
+
const res = await sendJson('PUT', `/api/bots/${encodeURIComponent(props.bot.larkAppId)}/session-group-tag-config`, { mode: next });
|
|
2361
|
+
if (res.ok && res.body.ok) {
|
|
2362
|
+
setStatus(s => ({ authorized: s?.authorized ?? false, tagMode: String(res.body.tagMode) }));
|
|
2363
|
+
}
|
|
2364
|
+
else {
|
|
2365
|
+
setErr(responseErrorText(res));
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
catch (e) {
|
|
2369
|
+
setErr(caughtErrorText(e));
|
|
2370
|
+
}
|
|
2371
|
+
finally {
|
|
2372
|
+
setModeBusy(false);
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
async function startAuth() {
|
|
2376
|
+
setAuthBusy(true);
|
|
2377
|
+
setErr(null);
|
|
2378
|
+
try {
|
|
2379
|
+
const res = await sendJson('POST', `/api/bots/${encodeURIComponent(props.bot.larkAppId)}/session-group-tag-auth`, {});
|
|
2380
|
+
if (!res.ok || !res.body.ok || !res.body.authUrl) {
|
|
2381
|
+
setErr(responseErrorText(res));
|
|
2382
|
+
return;
|
|
2383
|
+
}
|
|
2384
|
+
window.open(res.body.authUrl, '_blank', 'noopener');
|
|
2385
|
+
// 轮询授权结果:3s × 60 次(授权链接 5 分钟有效期同量级)。
|
|
2386
|
+
for (let i = 0; i < 60; i++) {
|
|
2387
|
+
await new Promise(r => setTimeout(r, 3000));
|
|
2388
|
+
if (await fetchStatus())
|
|
2389
|
+
return;
|
|
2390
|
+
}
|
|
2391
|
+
setErr(tr('botDefaults.sgTagAuthTimeout'));
|
|
2392
|
+
}
|
|
2393
|
+
catch (e) {
|
|
2394
|
+
setErr(caughtErrorText(e));
|
|
2395
|
+
}
|
|
2396
|
+
finally {
|
|
2397
|
+
setAuthBusy(false);
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
const tagMode = status?.tagMode ?? 'feed-group';
|
|
2401
|
+
const authorized = status?.authorized === true;
|
|
2402
|
+
const modeOptions = [
|
|
2403
|
+
{ value: 'feed-group', label: tr('botDefaults.sgTagModeFeedGroup') },
|
|
2404
|
+
{ value: 'chat-tag', label: tr('botDefaults.sgTagModeChatTag') },
|
|
2405
|
+
{ value: 'off', label: tr('botDefaults.sgTagModeOff') },
|
|
2406
|
+
];
|
|
2407
|
+
return (_jsx("div", { className: "bd-row", "data-session-group-tag-row": true, children: _jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.sgTagHelp'), children: tr('botDefaults.sgTag') }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }, children: [_jsx(DropdownField, { dataInput: "sessionGroupTagMode", ariaLabel: tr('botDefaults.sgTag'), value: tagMode, disabled: modeBusy || !status, options: modeOptions, onChange: next => void saveMode(next) }), tagMode === 'chat-tag' && (_jsx("span", { "data-sg-tag-state": "tenant", children: tr('botDefaults.sgTagChatTagNote') })), tagMode === 'feed-group' && (_jsxs(_Fragment, { children: [_jsx("span", { "data-sg-tag-state": authorized ? 'authorized' : 'unauthorized', children: authorized ? `🟢 ${tr('botDefaults.sgTagAuthorized')}` : `⚪ ${tr('botDefaults.sgTagUnauthorized')}` }), !authorized && (_jsx("button", { type: "button", className: "primary", "data-action": "session-group-tag-auth", disabled: authBusy, onClick: () => void startAuth(), children: authBusy ? tr('botDefaults.sgTagAuthWaiting') : tr('botDefaults.sgTagAuthStart') }))] })), err && _jsxs("span", { className: "status-error", children: ["\u2717 ", err] })] })] }) }));
|
|
2408
|
+
}
|
|
2106
2409
|
function regularGroupMode(bot) {
|
|
2107
2410
|
return bot.regularGroupReplyMode === 'chat' || bot.regularGroupReplyMode === 'new-topic' || bot.regularGroupReplyMode === 'shared'
|
|
2108
2411
|
? bot.regularGroupReplyMode
|
|
@@ -2437,6 +2740,7 @@ export function GrantSection(props) {
|
|
|
2437
2740
|
const tr = useT();
|
|
2438
2741
|
const [autoCard, setAutoCard] = useState(props.bot.autoGrantRequestCards !== false);
|
|
2439
2742
|
const [restrict, setRestrict] = useState(props.bot.restrictGrantCommands === true);
|
|
2743
|
+
const [p2pOpen, setP2pOpen] = useState(props.bot.p2pOpen === true);
|
|
2440
2744
|
const [duration, setDuration] = useState(typeof props.bot.grantDefaultDurationMs === 'number' ? props.bot.grantDefaultDurationMs : null);
|
|
2441
2745
|
const [durationInput, setDurationInput] = useState(String(props.bot.grantDefaultDurationMs ?? DEFAULT_GRANT_DURATION_MS));
|
|
2442
2746
|
const [quota, setQuota] = useState(typeof props.bot.messageQuotaDefaultLimit === 'number' ? props.bot.messageQuotaDefaultLimit : null);
|
|
@@ -2450,6 +2754,9 @@ export function GrantSection(props) {
|
|
|
2450
2754
|
useEffect(() => {
|
|
2451
2755
|
setRestrict(props.bot.restrictGrantCommands === true);
|
|
2452
2756
|
}, [props.bot.restrictGrantCommands]);
|
|
2757
|
+
useEffect(() => {
|
|
2758
|
+
setP2pOpen(props.bot.p2pOpen === true);
|
|
2759
|
+
}, [props.bot.p2pOpen]);
|
|
2453
2760
|
useEffect(() => {
|
|
2454
2761
|
const nextDuration = typeof props.bot.grantDefaultDurationMs === 'number' ? props.bot.grantDefaultDurationMs : null;
|
|
2455
2762
|
setDuration(nextDuration);
|
|
@@ -2462,7 +2769,9 @@ export function GrantSection(props) {
|
|
|
2462
2769
|
}, [props.bot.messageQuotaDefaultLimit]);
|
|
2463
2770
|
async function savePatch(patch, key, rollback) {
|
|
2464
2771
|
setBusy(key);
|
|
2465
|
-
setStatus(
|
|
2772
|
+
setStatus(key === 'duration' || key === 'quota'
|
|
2773
|
+
? { text: tr('botDefaults.grantDefaultsSaving') }
|
|
2774
|
+
: null);
|
|
2466
2775
|
try {
|
|
2467
2776
|
const res = await sendJson('PUT', `/api/bots/${encodeURIComponent(props.bot.larkAppId)}/grant-prefs`, patch);
|
|
2468
2777
|
if (res.ok && res.body.ok) {
|
|
@@ -2470,6 +2779,7 @@ export function GrantSection(props) {
|
|
|
2470
2779
|
const nextQuota = typeof res.body.messageQuotaDefaultLimit === 'number' ? res.body.messageQuotaDefaultLimit : null;
|
|
2471
2780
|
setAutoCard(res.body.autoGrantRequestCards !== false);
|
|
2472
2781
|
setRestrict(res.body.restrictGrantCommands === true);
|
|
2782
|
+
setP2pOpen(res.body.p2pOpen === true);
|
|
2473
2783
|
setDuration(nextDuration);
|
|
2474
2784
|
setQuota(nextQuota);
|
|
2475
2785
|
if ('grantDefaultDurationMs' in patch)
|
|
@@ -2480,10 +2790,11 @@ export function GrantSection(props) {
|
|
|
2480
2790
|
props.patchBot(props.bot.larkAppId, {
|
|
2481
2791
|
autoGrantRequestCards: res.body.autoGrantRequestCards !== false,
|
|
2482
2792
|
restrictGrantCommands: res.body.restrictGrantCommands === true,
|
|
2793
|
+
p2pOpen: res.body.p2pOpen === true,
|
|
2483
2794
|
grantDefaultDurationMs: nextDuration,
|
|
2484
2795
|
messageQuotaDefaultLimit: nextQuota,
|
|
2485
2796
|
});
|
|
2486
|
-
if (
|
|
2797
|
+
if ('messageQuotaDefaultLimit' in patch)
|
|
2487
2798
|
setQuotaError(null);
|
|
2488
2799
|
setStatus({ text: `✓ ${tr('botDefaults.cardPrefSaved')}`, ok: true });
|
|
2489
2800
|
}
|
|
@@ -2500,30 +2811,34 @@ export function GrantSection(props) {
|
|
|
2500
2811
|
setBusy(null);
|
|
2501
2812
|
}
|
|
2502
2813
|
}
|
|
2503
|
-
function
|
|
2504
|
-
|
|
2505
|
-
const quotaChanged = parsed !== quota;
|
|
2814
|
+
function saveDuration(nextInput) {
|
|
2815
|
+
setDurationInput(nextInput);
|
|
2506
2816
|
setStatus(null);
|
|
2507
|
-
|
|
2508
|
-
|| (typeof parsed === 'number' && parsed > MAX_GRANT_QUOTA))) {
|
|
2509
|
-
setQuotaError(tr('botDefaults.quotaInvalid'));
|
|
2510
|
-
return;
|
|
2511
|
-
}
|
|
2512
|
-
setQuotaError(null);
|
|
2513
|
-
const durationMs = Number(durationInput);
|
|
2817
|
+
const durationMs = Number(nextInput);
|
|
2514
2818
|
if (!GRANT_DURATION_VALUES.includes(durationMs)) {
|
|
2515
2819
|
setStatus({ text: `✗ ${tr('botDefaults.grantDurationInvalid')}` });
|
|
2516
2820
|
return;
|
|
2517
2821
|
}
|
|
2518
|
-
const
|
|
2519
|
-
if (
|
|
2520
|
-
|
|
2822
|
+
const nextDuration = durationMs === DEFAULT_GRANT_DURATION_MS ? null : durationMs;
|
|
2823
|
+
if (nextDuration === duration)
|
|
2824
|
+
return;
|
|
2825
|
+
const previousInput = String(duration ?? DEFAULT_GRANT_DURATION_MS);
|
|
2826
|
+
void savePatch({ grantDefaultDurationMs: nextDuration }, 'duration', () => setDurationInput(previousInput));
|
|
2827
|
+
}
|
|
2828
|
+
function saveQuota() {
|
|
2829
|
+
const parsed = positiveIntegerOrNull(quotaInput);
|
|
2830
|
+
const quotaChanged = parsed !== quota;
|
|
2831
|
+
setStatus(null);
|
|
2832
|
+
if (!quotaChanged) {
|
|
2833
|
+
setQuotaError(null);
|
|
2834
|
+
return;
|
|
2521
2835
|
}
|
|
2522
|
-
if (
|
|
2523
|
-
|
|
2836
|
+
if (parsed === 'invalid' || (typeof parsed === 'number' && parsed > MAX_GRANT_QUOTA)) {
|
|
2837
|
+
setQuotaError(tr('botDefaults.quotaInvalid'));
|
|
2838
|
+
return;
|
|
2524
2839
|
}
|
|
2525
|
-
|
|
2526
|
-
|
|
2840
|
+
setQuotaError(null);
|
|
2841
|
+
void savePatch({ messageQuotaDefaultLimit: parsed }, 'quota');
|
|
2527
2842
|
}
|
|
2528
2843
|
const durationOptions = [
|
|
2529
2844
|
{ value: String(DEFAULT_GRANT_DURATION_MS), label: tr('botDefaults.grantDuration1Hour') },
|
|
@@ -2535,11 +2850,22 @@ export function GrantSection(props) {
|
|
|
2535
2850
|
const currentDurationLabel = currentDuration === DEFAULT_GRANT_DURATION_MS
|
|
2536
2851
|
? tr('botDefaults.grantDuration1HourValue')
|
|
2537
2852
|
: String(durationOptions.find(option => option.value === String(currentDuration))?.label ?? '');
|
|
2538
|
-
const
|
|
2539
|
-
|
|
2540
|
-
|
|
2853
|
+
const quotaHelp = quota === null
|
|
2854
|
+
? tr('botDefaults.quotaHelpBuiltIn', { count: DEFAULT_GRANT_QUOTA })
|
|
2855
|
+
: quota > MAX_GRANT_QUOTA
|
|
2856
|
+
? tr('botDefaults.quotaHelpLegacy', {
|
|
2857
|
+
cardCount: MAX_GRANT_QUOTA,
|
|
2858
|
+
oncallCount: quota,
|
|
2859
|
+
defaultCount: DEFAULT_GRANT_QUOTA,
|
|
2860
|
+
})
|
|
2861
|
+
: tr('botDefaults.quotaHelpCustom', {
|
|
2862
|
+
count: quota,
|
|
2863
|
+
defaultCount: DEFAULT_GRANT_QUOTA,
|
|
2864
|
+
});
|
|
2541
2865
|
const currentState = quota === null
|
|
2542
|
-
? tr(
|
|
2866
|
+
? tr(duration === null
|
|
2867
|
+
? 'botDefaults.grantDefaultsCurrentBuiltIn'
|
|
2868
|
+
: 'botDefaults.grantDefaultsCurrentCustomBuiltInQuota', {
|
|
2543
2869
|
duration: currentDurationLabel,
|
|
2544
2870
|
count: DEFAULT_GRANT_QUOTA,
|
|
2545
2871
|
})
|
|
@@ -2561,17 +2887,23 @@ export function GrantSection(props) {
|
|
|
2561
2887
|
const previous = restrict;
|
|
2562
2888
|
setRestrict(checked);
|
|
2563
2889
|
void savePatch({ restrictGrantCommands: checked }, 'restrict', () => setRestrict(previous));
|
|
2890
|
+
} }), _jsx(ToggleRow, { checked: p2pOpen, disabled: busy !== null, dataAction: "toggle-p2p-open", title: tr('botDefaults.p2pOpen'), help: tr('botDefaults.p2pOpenHelp'), onChange: checked => {
|
|
2891
|
+
const previous = p2pOpen;
|
|
2892
|
+
setP2pOpen(checked);
|
|
2893
|
+
void savePatch({ p2pOpen: checked }, 'p2pOpen', () => setP2pOpen(previous));
|
|
2564
2894
|
} })] }), _jsxs("form", { className: "bd-grant-defaults", noValidate: true, onSubmit: event => {
|
|
2565
2895
|
event.preventDefault();
|
|
2566
|
-
|
|
2567
|
-
}, children: [_jsx("div", { className: "bd-row bd-grant-duration", children: _jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.grantDurationHelp'), children: tr('botDefaults.grantDurationDefault') }), _jsx(DropdownField, { dataInput: "grantDefaultDurationMs", value: durationInput, options: durationOptions, disabled: busy !== null, ariaLabel: tr('botDefaults.grantDurationDefault'), onChange: value => {
|
|
2568
|
-
setDurationInput(value);
|
|
2569
|
-
setStatus(null);
|
|
2570
|
-
} })] }) }), _jsxs("div", { className: "bd-row bd-quota", children: [_jsxs("label", { children: [_jsx(FieldTitle, { help: tr('botDefaults.quotaHelp'), children: tr('botDefaults.quotaDefault') }), _jsx("input", { type: "number", min: 1, max: MAX_GRANT_QUOTA, step: 1, "data-input": "quotaLimit", placeholder: tr('botDefaults.quotaPlaceholder'), value: quotaInput, disabled: busy !== null, "aria-label": tr('botDefaults.quotaDefault'), "aria-invalid": quotaError ? true : undefined, "aria-describedby": quotaError ? 'grant-defaults-state grant-default-quota-error' : 'grant-defaults-state', onChange: event => {
|
|
2896
|
+
saveQuota();
|
|
2897
|
+
}, children: [_jsx("div", { className: "bd-row bd-grant-duration", children: _jsxs("div", { className: "bd-field", children: [_jsx(FieldTitle, { help: tr('botDefaults.grantDurationHelp'), children: tr('botDefaults.grantDurationDefault') }), _jsx(DropdownField, { dataInput: "grantDefaultDurationMs", value: durationInput, options: durationOptions, disabled: busy !== null, ariaLabel: tr('botDefaults.grantDurationDefault'), onChange: saveDuration })] }) }), _jsxs("div", { className: "bd-row bd-quota", children: [_jsxs("label", { children: [_jsx(FieldTitle, { help: quotaHelp, children: tr('botDefaults.quotaDefault') }), _jsx("input", { type: "number", min: 1, max: MAX_GRANT_QUOTA, step: 1, "data-input": "quotaLimit", placeholder: tr('botDefaults.quotaPlaceholder', { count: DEFAULT_GRANT_QUOTA }), value: quotaInput, disabled: busy !== null, "aria-label": tr('botDefaults.quotaDefault'), "aria-invalid": quotaError ? true : undefined, "aria-describedby": quotaError ? 'grant-defaults-state grant-default-quota-error' : 'grant-defaults-state', onChange: event => {
|
|
2571
2898
|
setQuotaInput(event.currentTarget.value);
|
|
2572
2899
|
setQuotaError(null);
|
|
2573
2900
|
setStatus(null);
|
|
2574
|
-
}
|
|
2901
|
+
}, onBlur: saveQuota, onKeyDown: event => {
|
|
2902
|
+
if (event.key !== 'Enter')
|
|
2903
|
+
return;
|
|
2904
|
+
event.preventDefault();
|
|
2905
|
+
event.currentTarget.blur();
|
|
2906
|
+
} })] }), quotaError ? _jsx("small", { id: "grant-default-quota-error", className: "bd-field-error", role: "alert", children: quotaError }) : null, _jsx("small", { id: "grant-defaults-state", "data-grant-defaults-state": true, children: currentState })] }), _jsx("div", { className: "actions", children: _jsx(StatusSpan, { status: status, attr: { 'data-grant-status': '' } }) })] })] }));
|
|
2575
2907
|
}
|
|
2576
2908
|
export function renderBotDefaultsPage(root) {
|
|
2577
2909
|
return mountReactPage(root, _jsx(BotDefaultsPage, {}));
|