@poolzin/pool-bot 2026.2.25 → 2026.2.26
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/acp/event-mapper.js +87 -22
- package/dist/acp/meta.js +12 -6
- package/dist/agents/agent-paths.js +8 -9
- package/dist/agents/agent-scope.js +7 -5
- package/dist/agents/auth-profiles/oauth.js +148 -64
- package/dist/agents/auth-profiles/session-override.js +13 -7
- package/dist/agents/bash-tools.exec-host-gateway.js +14 -4
- package/dist/agents/bash-tools.exec-runtime.js +2 -25
- package/dist/agents/bedrock-discovery.js +3 -1
- package/dist/agents/byteplus-models.js +97 -0
- package/dist/agents/chutes-oauth.js +1 -0
- package/dist/agents/cli-runner/helpers.js +4 -0
- package/dist/agents/compaction.js +41 -14
- package/dist/agents/doubao-models.js +121 -0
- package/dist/agents/failover-error.js +2 -0
- package/dist/agents/huggingface-models.js +5 -3
- package/dist/agents/live-model-filter.js +5 -0
- package/dist/agents/minimax-vlm.js +10 -8
- package/dist/agents/model-auth.js +6 -0
- package/dist/agents/model-catalog.js +3 -1
- package/dist/agents/model-selection.js +7 -1
- package/dist/agents/models-config.providers.js +93 -11
- package/dist/agents/ollama-stream.js +117 -4
- package/dist/agents/opencode-zen-models.js +22 -11
- package/dist/agents/pi-embedded-helpers/errors.js +55 -33
- package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
- package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
- package/dist/agents/pi-embedded-helpers.js +1 -1
- package/dist/agents/pi-embedded-runner/compact.js +29 -7
- package/dist/agents/pi-embedded-runner/extensions.js +28 -26
- package/dist/agents/pi-embedded-runner/google.js +20 -8
- package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
- package/dist/agents/pi-embedded-runner/run.js +71 -12
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
- package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
- package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
- package/dist/agents/pi-embedded-runner/thinking.js +42 -0
- package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
- package/dist/agents/pi-embedded-runner/utils.js +7 -10
- package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
- package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
- package/dist/agents/pi-embedded-subscribe.js +9 -4
- package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
- package/dist/agents/pi-embedded-utils.js +3 -0
- package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
- package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
- package/dist/agents/pi-settings.js +40 -0
- package/dist/agents/pi-tools.policy.js +2 -1
- package/dist/agents/provider/config-loader.js +1 -1
- package/dist/agents/sandbox/browser.js +170 -33
- package/dist/agents/sandbox/config-hash.js +14 -27
- package/dist/agents/sandbox/config.js +21 -2
- package/dist/agents/sandbox/constants.js +2 -0
- package/dist/agents/sandbox/docker.js +16 -2
- package/dist/agents/sandbox/novnc-auth.js +62 -0
- package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
- package/dist/agents/sandbox/shared.js +10 -6
- package/dist/agents/sandbox-paths.js +24 -11
- package/dist/agents/schema/clean-for-gemini.js +132 -85
- package/dist/agents/session-slug.js +10 -5
- package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
- package/dist/agents/session-tool-result-guard.js +3 -1
- package/dist/agents/session-transcript-repair.js +40 -6
- package/dist/agents/skills/bundled-dir.js +19 -5
- package/dist/agents/skills/env-overrides.js +124 -43
- package/dist/agents/skills/frontmatter.js +6 -6
- package/dist/agents/skills/plugin-skills.js +14 -7
- package/dist/agents/skills/workspace.js +1 -0
- package/dist/agents/subagent-announce.js +251 -49
- package/dist/agents/subagent-lifecycle-events.js +19 -0
- package/dist/agents/subagent-registry-cleanup.js +31 -0
- package/dist/agents/subagent-registry-completion.js +68 -0
- package/dist/agents/subagent-registry-queries.js +117 -0
- package/dist/agents/subagent-registry-state.js +46 -0
- package/dist/agents/subagent-registry.js +252 -221
- package/dist/agents/subagent-registry.store.js +1 -0
- package/dist/agents/subagent-registry.types.js +1 -0
- package/dist/agents/subagent-spawn.js +195 -7
- package/dist/agents/system-prompt.js +22 -6
- package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
- package/dist/agents/test-helpers/fast-core-tools.js +1 -17
- package/dist/agents/timeout.js +18 -6
- package/dist/agents/tool-call-id.js +1 -1
- package/dist/agents/tool-display-common.js +162 -29
- package/dist/agents/tool-images.js +82 -9
- package/dist/agents/tool-policy.js +51 -26
- package/dist/agents/tools/browser-tool.js +2 -2
- package/dist/agents/tools/canvas-tool.js +27 -1
- package/dist/agents/tools/common.js +45 -0
- package/dist/agents/tools/discord-actions-guild.js +4 -1
- package/dist/agents/tools/gateway-tool.js +3 -1
- package/dist/agents/tools/nodes-utils.js +1 -10
- package/dist/agents/tools/sessions-send-helpers.js +12 -6
- package/dist/agents/tools/sessions-spawn-tool.js +8 -2
- package/dist/agents/tools/subagents-tool.js +2 -1
- package/dist/agents/tools/whatsapp-actions.js +10 -2
- package/dist/agents/tools/whatsapp-target-auth.js +18 -0
- package/dist/agents/transcript-policy.js +22 -8
- package/dist/agents/venice-models.js +11 -3
- package/dist/auto-reply/commands-registry.data.js +51 -0
- package/dist/auto-reply/commands-registry.js +4 -3
- package/dist/auto-reply/group-activation.js +10 -5
- package/dist/auto-reply/inbound-debounce.js +10 -5
- package/dist/auto-reply/reply/abort.js +1 -1
- package/dist/auto-reply/reply/agent-runner-execution.js +4 -1
- package/dist/auto-reply/reply/bash-command.js +41 -39
- package/dist/auto-reply/reply/command-gates.js +25 -0
- package/dist/auto-reply/reply/commands-allowlist.js +111 -72
- package/dist/auto-reply/reply/commands-bash.js +6 -5
- package/dist/auto-reply/reply/commands-config.js +30 -28
- package/dist/auto-reply/reply/commands-core.js +2 -1
- package/dist/auto-reply/reply/commands-info.js +1 -0
- package/dist/auto-reply/reply/commands-models.js +65 -14
- package/dist/auto-reply/reply/commands-session.js +237 -82
- package/dist/auto-reply/reply/commands-setunset.js +45 -0
- package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
- package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
- package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
- package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
- package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
- package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
- package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
- package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
- package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
- package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
- package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
- package/dist/auto-reply/reply/commands-subagents.js +51 -587
- package/dist/auto-reply/reply/commands-tts.js +10 -5
- package/dist/auto-reply/reply/config-value.js +10 -5
- package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
- package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
- package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
- package/dist/auto-reply/reply/followup-runner.js +1 -0
- package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
- package/dist/auto-reply/reply/get-reply-directives.js +17 -28
- package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
- package/dist/auto-reply/reply/get-reply.js +71 -12
- package/dist/auto-reply/reply/model-selection.js +80 -39
- package/dist/auto-reply/reply/queue/enqueue.js +10 -5
- package/dist/auto-reply/reply/queue/state.js +13 -12
- package/dist/auto-reply/reply/reply-payloads.js +67 -36
- package/dist/auto-reply/reply/reply-reference.js +9 -8
- package/dist/auto-reply/reply/route-reply.js +15 -8
- package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
- package/dist/auto-reply/reply/session.js +22 -6
- package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
- package/dist/auto-reply/reply/subagents-utils.js +56 -30
- package/dist/auto-reply/reply/typing.js +46 -21
- package/dist/auto-reply/send-policy.js +14 -7
- package/dist/auto-reply/status.js +140 -16
- package/dist/auto-reply/templating.js +10 -5
- package/dist/auto-reply/thinking.js +7 -16
- package/dist/auto-reply/tokens.js +21 -5
- package/dist/browser/bridge-server.js +36 -20
- package/dist/browser/cdp.helpers.js +7 -14
- package/dist/browser/cdp.js +35 -15
- package/dist/browser/chrome.profile-decoration.js +7 -4
- package/dist/browser/config.js +4 -0
- package/dist/browser/extension-relay-auth.js +55 -0
- package/dist/browser/extension-relay.js +74 -29
- package/dist/browser/navigation-guard.js +9 -1
- package/dist/browser/paths.js +77 -0
- package/dist/browser/profiles.js +13 -8
- package/dist/browser/pw-ai-module.js +10 -5
- package/dist/browser/pw-session.js +76 -39
- package/dist/browser/pw-tools-core.interactions.js +14 -7
- package/dist/browser/pw-tools-core.state.js +12 -6
- package/dist/browser/routes/agent.act.js +2 -2
- package/dist/browser/server-context.js +7 -0
- package/dist/build-info.json +3 -3
- package/dist/channels/allow-from.js +2 -1
- package/dist/channels/allowlists/resolve-utils.js +43 -19
- package/dist/channels/channel-config.js +14 -7
- package/dist/channels/draft-stream-loop.js +7 -0
- package/dist/channels/model-overrides.js +82 -0
- package/dist/channels/plugins/normalize/imessage.js +14 -7
- package/dist/channels/plugins/normalize/slack.js +10 -5
- package/dist/channels/plugins/normalize/telegram.js +14 -7
- package/dist/channels/plugins/outbound/discord.js +80 -8
- package/dist/channels/plugins/outbound/signal.js +11 -11
- package/dist/channels/plugins/setup-helpers.js +10 -5
- package/dist/channels/sender-label.js +14 -7
- package/dist/channels/session.js +4 -2
- package/dist/channels/status-reactions.js +297 -0
- package/dist/cli/banner.js +1 -1
- package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
- package/dist/cli/cli-name.js +11 -11
- package/dist/cli/cli-utils.js +13 -3
- package/dist/cli/command-format.js +1 -1
- package/dist/cli/config-cli.js +1 -1
- package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
- package/dist/cli/daemon-cli/lifecycle.js +64 -2
- package/dist/cli/daemon-cli/restart-health.js +126 -0
- package/dist/cli/daemon-cli/status.gather.js +9 -13
- package/dist/cli/daemon-cli/status.print.js +2 -10
- package/dist/cli/deps.js +27 -22
- package/dist/cli/gateway-cli/run-loop.js +23 -5
- package/dist/cli/node-cli/register.js +14 -5
- package/dist/cli/nodes-media-utils.js +7 -2
- package/dist/cli/outbound-send-deps.js +2 -9
- package/dist/cli/outbound-send-mapping.js +11 -0
- package/dist/cli/pairing-cli.js +40 -14
- package/dist/cli/plugins-cli.js +34 -41
- package/dist/cli/ports.js +11 -10
- package/dist/cli/program/command-registry.js +2 -11
- package/dist/cli/program/command-tree.js +16 -0
- package/dist/cli/program/preaction.js +13 -9
- package/dist/cli/program/register.configure.js +3 -18
- package/dist/cli/program/register.maintenance.js +2 -2
- package/dist/cli/program/register.onboard.js +2 -0
- package/dist/cli/program/register.status-health-sessions.js +16 -17
- package/dist/cli/program/register.subclis.js +93 -52
- package/dist/cli/route.js +11 -7
- package/dist/cli/system-cli.js +36 -46
- package/dist/cli/update-cli/shared.js +22 -9
- package/dist/cli/update-cli/update-command.js +89 -14
- package/dist/cli/update-cli/wizard.js +6 -12
- package/dist/commands/agent/run-context.js +18 -5
- package/dist/commands/agent/session-store.js +17 -4
- package/dist/commands/agent.js +22 -2
- package/dist/commands/agents.bindings.js +14 -7
- package/dist/commands/agents.commands.add.js +13 -9
- package/dist/commands/agents.commands.identity.js +12 -6
- package/dist/commands/agents.commands.list.js +11 -6
- package/dist/commands/agents.config.js +8 -10
- package/dist/commands/agents.providers.js +12 -6
- package/dist/commands/auth-choice-options.js +103 -75
- package/dist/commands/auth-choice.apply.byteplus.js +55 -0
- package/dist/commands/auth-choice.apply.js +4 -0
- package/dist/commands/auth-choice.apply.minimax.js +61 -13
- package/dist/commands/auth-choice.apply.openai.js +3 -1
- package/dist/commands/auth-choice.apply.volcengine.js +55 -0
- package/dist/commands/auth-choice.preferred-provider.js +2 -0
- package/dist/commands/channels/remove.js +13 -6
- package/dist/commands/channels/shared.js +4 -14
- package/dist/commands/configure.commands.js +14 -0
- package/dist/commands/configure.gateway.js +2 -4
- package/dist/commands/configure.js +1 -1
- package/dist/commands/configure.shared.js +11 -0
- package/dist/commands/daemon-install-helpers.js +2 -2
- package/dist/commands/dashboard.js +12 -10
- package/dist/commands/docs.js +14 -8
- package/dist/commands/doctor-config-flow.js +11 -9
- package/dist/commands/doctor-legacy-config.js +281 -0
- package/dist/commands/doctor-state-integrity.js +99 -23
- package/dist/commands/doctor-update.js +12 -9
- package/dist/commands/models/list.list-command.js +7 -5
- package/dist/commands/models/set-image.js +2 -21
- package/dist/commands/node-daemon-install-helpers.js +10 -8
- package/dist/commands/onboard-auth.config-minimax.js +54 -80
- package/dist/commands/onboard-auth.config-opencode.js +2 -18
- package/dist/commands/onboard-auth.credentials.js +90 -13
- package/dist/commands/onboard-auth.js +1 -1
- package/dist/commands/onboard-auth.models.js +6 -5
- package/dist/commands/onboard-hooks.js +1 -1
- package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
- package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
- package/dist/commands/onboard-provider-auth-flags.js +14 -0
- package/dist/commands/onboard-remote.js +14 -7
- package/dist/commands/onboard.js +11 -13
- package/dist/commands/sandbox-display.js +6 -5
- package/dist/commands/status-all/diagnosis.js +14 -10
- package/dist/commands/status-all/format.js +1 -0
- package/dist/commands/status.gateway-probe.js +1 -16
- package/dist/commands/systemd-linger.js +12 -6
- package/dist/config/agent-limits.js +2 -0
- package/dist/config/commands.js +30 -16
- package/dist/config/config-paths.js +9 -11
- package/dist/config/defaults.js +22 -2
- package/dist/config/discord-preview-streaming.js +104 -0
- package/dist/config/env-vars.js +37 -8
- package/dist/config/includes.js +4 -0
- package/dist/config/io.js +97 -12
- package/dist/config/legacy.migrations.part-1.js +189 -78
- package/dist/config/legacy.shared.js +3 -1
- package/dist/config/merge-patch.js +4 -0
- package/dist/config/prototype-keys.js +4 -0
- package/dist/config/schema.help.js +44 -7
- package/dist/config/schema.labels.js +38 -6
- package/dist/config/sessions/delivery-info.js +10 -3
- package/dist/config/sessions/main-session.js +10 -5
- package/dist/config/sessions/session-file.js +33 -0
- package/dist/config/sessions/session-key.js +10 -5
- package/dist/config/sessions/store.js +1 -1
- package/dist/config/sessions.js +1 -0
- package/dist/config/zod-schema.agent-runtime.js +11 -0
- package/dist/config/zod-schema.js +148 -13
- package/dist/config/zod-schema.providers-core.js +78 -4
- package/dist/config/zod-schema.providers.js +6 -1
- package/dist/config/zod-schema.session.js +41 -2
- package/dist/cron/run-log.js +3 -0
- package/dist/cron/schedule.js +21 -10
- package/dist/cron/service/ops.js +35 -21
- package/dist/cron/service/timer.js +116 -16
- package/dist/cron/stagger.js +3 -1
- package/dist/discord/api.js +12 -6
- package/dist/discord/draft-chunking.js +22 -0
- package/dist/discord/draft-stream.js +124 -0
- package/dist/discord/monitor/agent-components.js +1 -1
- package/dist/discord/monitor/commands.js +5 -0
- package/dist/discord/monitor/gateway-plugin.js +2 -1
- package/dist/discord/monitor/listeners.js +37 -27
- package/dist/discord/monitor/message-handler.js +4 -1
- package/dist/discord/monitor/message-handler.preflight.js +65 -8
- package/dist/discord/monitor/message-handler.process.js +246 -217
- package/dist/discord/monitor/message-utils.js +143 -6
- package/dist/discord/monitor/model-picker-preferences.js +143 -0
- package/dist/discord/monitor/model-picker.js +651 -0
- package/dist/discord/monitor/native-command.js +573 -16
- package/dist/discord/monitor/provider.allowlist.js +223 -0
- package/dist/discord/monitor/provider.js +275 -347
- package/dist/discord/monitor/provider.lifecycle.js +100 -0
- package/dist/discord/monitor/reply-delivery.js +123 -16
- package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
- package/dist/discord/monitor/thread-bindings.js +4 -0
- package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
- package/dist/discord/monitor/thread-bindings.manager.js +423 -0
- package/dist/discord/monitor/thread-bindings.messages.js +55 -0
- package/dist/discord/monitor/thread-bindings.state.js +358 -0
- package/dist/discord/monitor/thread-bindings.types.js +6 -0
- package/dist/discord/resolve-users.js +33 -21
- package/dist/discord/send.channels.js +15 -0
- package/dist/discord/send.js +3 -2
- package/dist/discord/send.outbound.js +82 -26
- package/dist/discord/send.permissions.js +83 -30
- package/dist/discord/send.reactions.js +8 -4
- package/dist/discord/token.js +10 -5
- package/dist/discord/voice/command.js +263 -0
- package/dist/discord/voice/manager.js +531 -0
- package/dist/gateway/auth.js +34 -10
- package/dist/gateway/call.js +4 -16
- package/dist/gateway/client.js +28 -4
- package/dist/gateway/config-reload.js +3 -4
- package/dist/gateway/control-ui.js +219 -96
- package/dist/gateway/hooks-mapping.js +88 -38
- package/dist/gateway/http-auth-helpers.js +3 -2
- package/dist/gateway/http-endpoint-helpers.js +1 -0
- package/dist/gateway/net.js +54 -12
- package/dist/gateway/node-invoke-system-run-approval.js +14 -35
- package/dist/gateway/node-registry.js +10 -5
- package/dist/gateway/openai-http.js +1 -0
- package/dist/gateway/openresponses-http.js +1 -0
- package/dist/gateway/origin-check.js +1 -18
- package/dist/gateway/protocol/index.js +4 -3
- package/dist/gateway/protocol/schema/cron.js +1 -0
- package/dist/gateway/protocol/schema/devices.js +1 -0
- package/dist/gateway/protocol/schema/protocol-schemas.js +2 -1
- package/dist/gateway/protocol/schema/sessions.js +6 -0
- package/dist/gateway/role-policy.js +17 -0
- package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
- package/dist/gateway/server/ws-connection/message-handler.js +175 -148
- package/dist/gateway/server-chat.js +83 -25
- package/dist/gateway/server-constants.js +10 -9
- package/dist/gateway/server-cron.js +1 -0
- package/dist/gateway/server-http.js +16 -7
- package/dist/gateway/server-maintenance.js +20 -5
- package/dist/gateway/server-methods/chat.js +10 -6
- package/dist/gateway/server-methods/config.js +12 -14
- package/dist/gateway/server-methods/devices.js +17 -3
- package/dist/gateway/server-methods/models.js +11 -1
- package/dist/gateway/server-methods/sessions.js +64 -8
- package/dist/gateway/server-methods/usage.js +162 -75
- package/dist/gateway/server-node-events.js +29 -0
- package/dist/gateway/server-runtime-config.js +34 -13
- package/dist/gateway/server-startup-memory.js +17 -11
- package/dist/gateway/session-utils.fs.js +32 -34
- package/dist/gateway/sessions-resolve.js +17 -5
- package/dist/gateway/test-helpers.openai-mock.js +14 -7
- package/dist/gateway/tools-invoke-http.js +21 -10
- package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
- package/dist/hooks/bundled/command-logger/handler.js +7 -2
- package/dist/hooks/bundled/session-memory/handler.js +6 -5
- package/dist/hooks/frontmatter.js +6 -6
- package/dist/hooks/gmail-watcher.js +11 -6
- package/dist/hooks/internal-hooks.js +11 -1
- package/dist/hooks/llm-slug-generator.js +4 -1
- package/dist/hooks/workspace.js +47 -17
- package/dist/imessage/accounts.js +9 -20
- package/dist/imessage/monitor/inbound-processing.js +2 -1
- package/dist/infra/archive.js +174 -73
- package/dist/infra/control-ui-assets.js +14 -6
- package/dist/infra/device-pairing.js +108 -29
- package/dist/infra/env.js +10 -5
- package/dist/infra/exec-approvals-allowlist.js +122 -0
- package/dist/infra/exec-approvals-analysis.js +34 -3
- package/dist/infra/exec-approvals.js +5 -17
- package/dist/infra/exec-safe-bin-policy.js +53 -45
- package/dist/infra/fs-safe.js +71 -39
- package/dist/infra/gateway-lock.js +6 -2
- package/dist/infra/heartbeat-wake.js +6 -12
- package/dist/infra/host-env-security-policy.json +19 -0
- package/dist/infra/host-env-security.js +66 -0
- package/dist/infra/net/ssrf.js +131 -38
- package/dist/infra/outbound/bound-delivery-router.js +88 -0
- package/dist/infra/outbound/channel-selection.js +12 -6
- package/dist/infra/outbound/envelope.js +1 -1
- package/dist/infra/outbound/format.js +12 -6
- package/dist/infra/outbound/payloads.js +14 -7
- package/dist/infra/outbound/session-binding-service.js +123 -0
- package/dist/infra/path-guards.js +25 -0
- package/dist/infra/provider-usage.fetch.codex.js +7 -15
- package/dist/infra/provider-usage.fetch.gemini.js +14 -11
- package/dist/infra/provider-usage.fetch.shared.js +30 -1
- package/dist/infra/provider-usage.fetch.zai.js +10 -9
- package/dist/infra/retry-policy.js +4 -2
- package/dist/infra/retry.js +9 -5
- package/dist/infra/session-cost-usage.js +107 -59
- package/dist/infra/session-maintenance-warning.js +3 -1
- package/dist/infra/shell-env.js +98 -34
- package/dist/infra/ssh-config.js +12 -6
- package/dist/infra/system-run-command.js +49 -4
- package/dist/infra/update-channels.js +10 -5
- package/dist/line/accounts.js +5 -7
- package/dist/line/bot-access.js +8 -20
- package/dist/line/bot-handlers.js +3 -1
- package/dist/link-understanding/detect.js +15 -7
- package/dist/media/constants.js +15 -6
- package/dist/media/image-ops.js +7 -0
- package/dist/media/local-roots.js +3 -2
- package/dist/media-understanding/apply.js +4 -1
- package/dist/media-understanding/concurrency.js +8 -20
- package/dist/memory/backend-config.js +45 -6
- package/dist/memory/embeddings.js +10 -4
- package/dist/memory/fs-utils.js +23 -0
- package/dist/memory/manager-search.js +12 -6
- package/dist/memory/manager-sync-ops.js +12 -2
- package/dist/memory/qmd-manager.js +466 -53
- package/dist/memory/query-expansion.js +167 -3
- package/dist/memory/status-format.js +10 -5
- package/dist/memory/sync-memory-files.js +1 -1
- package/dist/node-host/invoke-system-run.js +281 -0
- package/dist/node-host/invoke.js +55 -337
- package/dist/pairing/pairing-store.js +22 -0
- package/dist/plugin-sdk/allow-from.js +1 -1
- package/dist/plugin-sdk/command-auth.js +3 -1
- package/dist/plugin-sdk/index.js +6 -3
- package/dist/plugin-sdk/webhook-targets.js +32 -0
- package/dist/plugins/bundled-dir.js +9 -6
- package/dist/plugins/hooks.js +50 -0
- package/dist/plugins/install.js +28 -16
- package/dist/plugins/runtime.js +3 -17
- package/dist/plugins/update.js +78 -12
- package/dist/process/spawn-utils.js +14 -7
- package/dist/providers/github-copilot-token.js +11 -6
- package/dist/providers/qwen-portal-oauth.js +14 -6
- package/dist/routing/account-id.js +30 -0
- package/dist/routing/resolve-route.js +3 -7
- package/dist/routing/session-key.js +2 -16
- package/dist/security/audit-channel.js +93 -2
- package/dist/security/audit-extra.async.js +159 -5
- package/dist/security/audit-extra.js +1 -1
- package/dist/security/audit-extra.sync.js +85 -6
- package/dist/security/audit.js +40 -4
- package/dist/security/dm-policy-shared.js +44 -0
- package/dist/security/external-content.js +26 -6
- package/dist/shared/entry-status.js +6 -0
- package/dist/shared/frontmatter.js +5 -5
- package/dist/shared/node-match.js +11 -4
- package/dist/shared/operator-scope-compat.js +8 -3
- package/dist/signal/accounts.js +7 -20
- package/dist/signal/monitor/event-handler.js +3 -1
- package/dist/slack/accounts.js +6 -19
- package/dist/slack/actions.js +11 -3
- package/dist/slack/monitor/auth.js +1 -1
- package/dist/slack/monitor/message-handler/dispatch.js +50 -29
- package/dist/slack/monitor/replies.js +15 -7
- package/dist/slack/monitor/slash.js +22 -13
- package/dist/slack/resolve-channels.js +10 -5
- package/dist/slack/send.js +102 -12
- package/dist/slack/stream-mode.js +10 -0
- package/dist/slack/streaming.js +4 -2
- package/dist/telegram/accounts.js +19 -14
- package/dist/telegram/bot/helpers.js +3 -5
- package/dist/telegram/bot-access.js +35 -36
- package/dist/telegram/bot-handlers.js +120 -148
- package/dist/telegram/bot-message-context.js +68 -9
- package/dist/telegram/bot-message-dispatch.js +155 -90
- package/dist/telegram/bot-native-commands.js +16 -0
- package/dist/telegram/draft-stream.js +14 -1
- package/dist/telegram/inline-buttons.js +5 -15
- package/dist/telegram/monitor.js +11 -7
- package/dist/telegram/network-config.js +19 -7
- package/dist/telegram/send.js +3 -2
- package/dist/telegram/sent-message-cache.js +5 -6
- package/dist/telegram/status-reaction-variants.js +208 -0
- package/dist/telegram/sticker-cache.js +11 -9
- package/dist/terminal/theme.js +12 -12
- package/dist/tts/tts.js +80 -567
- package/dist/tui/components/chat-log.js +41 -8
- package/dist/tui/theme/theme.js +10 -12
- package/dist/tui/tui-local-shell.js +16 -6
- package/dist/tui/tui.js +58 -6
- package/dist/utils/account-id.js +2 -4
- package/dist/utils/boolean.js +10 -5
- package/dist/utils/directive-tags.js +11 -0
- package/dist/utils/queue-helpers.js +67 -12
- package/dist/web/auto-reply/deliver-reply.js +8 -4
- package/dist/web/auto-reply/mentions.js +10 -5
- package/dist/web/auto-reply/monitor/group-members.js +14 -7
- package/dist/web/auto-reply/monitor/process-message.js +45 -24
- package/dist/web/inbound/access-control.js +5 -2
- package/dist/web/login-qr.js +12 -6
- package/dist/web/media.js +123 -16
- package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
- package/extensions/bluebubbles/src/monitor.ts +208 -1950
- package/package.json +1 -1
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import type { PoolBotConfig } from "poolbot/plugin-sdk";
|
|
2
2
|
import {
|
|
3
3
|
createReplyPrefixOptions,
|
|
4
|
+
evictOldHistoryKeys,
|
|
4
5
|
logAckFailure,
|
|
5
6
|
logInboundDrop,
|
|
6
7
|
logTypingFailure,
|
|
8
|
+
recordPendingHistoryEntryIfEnabled,
|
|
7
9
|
resolveAckReaction,
|
|
10
|
+
resolveDmGroupAccessDecision,
|
|
11
|
+
resolveEffectiveAllowFromLists,
|
|
8
12
|
resolveControlCommandGate,
|
|
13
|
+
stripMarkdown,
|
|
14
|
+
type HistoryEntry,
|
|
9
15
|
} from "poolbot/plugin-sdk";
|
|
10
16
|
import { downloadBlueBubblesAttachment } from "./attachments.js";
|
|
11
17
|
import { markBlueBubblesChatRead, sendBlueBubblesTyping } from "./chat.js";
|
|
18
|
+
import { fetchBlueBubblesHistory } from "./history.js";
|
|
12
19
|
import { sendBlueBubblesMedia } from "./media-send.js";
|
|
13
20
|
import {
|
|
14
21
|
buildMessagePlaceholder,
|
|
@@ -40,6 +47,135 @@ import { formatBlueBubblesChatTarget, isAllowedBlueBubblesSender } from "./targe
|
|
|
40
47
|
const DEFAULT_TEXT_LIMIT = 4000;
|
|
41
48
|
const invalidAckReactions = new Set<string>();
|
|
42
49
|
const REPLY_DIRECTIVE_TAG_RE = /\[\[\s*(?:reply_to_current|reply_to\s*:\s*[^\]\n]+)\s*\]\]/gi;
|
|
50
|
+
const PENDING_OUTBOUND_MESSAGE_ID_TTL_MS = 2 * 60 * 1000;
|
|
51
|
+
|
|
52
|
+
type PendingOutboundMessageId = {
|
|
53
|
+
id: number;
|
|
54
|
+
accountId: string;
|
|
55
|
+
sessionKey: string;
|
|
56
|
+
outboundTarget: string;
|
|
57
|
+
chatGuid?: string;
|
|
58
|
+
chatIdentifier?: string;
|
|
59
|
+
chatId?: number;
|
|
60
|
+
snippetRaw: string;
|
|
61
|
+
snippetNorm: string;
|
|
62
|
+
isMediaSnippet: boolean;
|
|
63
|
+
createdAt: number;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const pendingOutboundMessageIds: PendingOutboundMessageId[] = [];
|
|
67
|
+
let pendingOutboundMessageIdCounter = 0;
|
|
68
|
+
|
|
69
|
+
function trimOrUndefined(value?: string | null): string | undefined {
|
|
70
|
+
const trimmed = value?.trim();
|
|
71
|
+
return trimmed ? trimmed : undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function normalizeSnippet(value: string): string {
|
|
75
|
+
return stripMarkdown(value).replace(/\s+/g, " ").trim().toLowerCase();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function prunePendingOutboundMessageIds(now = Date.now()): void {
|
|
79
|
+
const cutoff = now - PENDING_OUTBOUND_MESSAGE_ID_TTL_MS;
|
|
80
|
+
for (let i = pendingOutboundMessageIds.length - 1; i >= 0; i--) {
|
|
81
|
+
if (pendingOutboundMessageIds[i].createdAt < cutoff) {
|
|
82
|
+
pendingOutboundMessageIds.splice(i, 1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function rememberPendingOutboundMessageId(entry: {
|
|
88
|
+
accountId: string;
|
|
89
|
+
sessionKey: string;
|
|
90
|
+
outboundTarget: string;
|
|
91
|
+
chatGuid?: string;
|
|
92
|
+
chatIdentifier?: string;
|
|
93
|
+
chatId?: number;
|
|
94
|
+
snippet: string;
|
|
95
|
+
}): number {
|
|
96
|
+
prunePendingOutboundMessageIds();
|
|
97
|
+
pendingOutboundMessageIdCounter += 1;
|
|
98
|
+
const snippetRaw = entry.snippet.trim();
|
|
99
|
+
const snippetNorm = normalizeSnippet(snippetRaw);
|
|
100
|
+
pendingOutboundMessageIds.push({
|
|
101
|
+
id: pendingOutboundMessageIdCounter,
|
|
102
|
+
accountId: entry.accountId,
|
|
103
|
+
sessionKey: entry.sessionKey,
|
|
104
|
+
outboundTarget: entry.outboundTarget,
|
|
105
|
+
chatGuid: trimOrUndefined(entry.chatGuid),
|
|
106
|
+
chatIdentifier: trimOrUndefined(entry.chatIdentifier),
|
|
107
|
+
chatId: typeof entry.chatId === "number" ? entry.chatId : undefined,
|
|
108
|
+
snippetRaw,
|
|
109
|
+
snippetNorm,
|
|
110
|
+
isMediaSnippet: snippetRaw.toLowerCase().startsWith("<media:"),
|
|
111
|
+
createdAt: Date.now(),
|
|
112
|
+
});
|
|
113
|
+
return pendingOutboundMessageIdCounter;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function forgetPendingOutboundMessageId(id: number): void {
|
|
117
|
+
const index = pendingOutboundMessageIds.findIndex((entry) => entry.id === id);
|
|
118
|
+
if (index >= 0) {
|
|
119
|
+
pendingOutboundMessageIds.splice(index, 1);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function chatsMatch(
|
|
124
|
+
left: Pick<PendingOutboundMessageId, "chatGuid" | "chatIdentifier" | "chatId">,
|
|
125
|
+
right: { chatGuid?: string; chatIdentifier?: string; chatId?: number },
|
|
126
|
+
): boolean {
|
|
127
|
+
const leftGuid = trimOrUndefined(left.chatGuid);
|
|
128
|
+
const rightGuid = trimOrUndefined(right.chatGuid);
|
|
129
|
+
if (leftGuid && rightGuid) {
|
|
130
|
+
return leftGuid === rightGuid;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const leftIdentifier = trimOrUndefined(left.chatIdentifier);
|
|
134
|
+
const rightIdentifier = trimOrUndefined(right.chatIdentifier);
|
|
135
|
+
if (leftIdentifier && rightIdentifier) {
|
|
136
|
+
return leftIdentifier === rightIdentifier;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const leftChatId = typeof left.chatId === "number" ? left.chatId : undefined;
|
|
140
|
+
const rightChatId = typeof right.chatId === "number" ? right.chatId : undefined;
|
|
141
|
+
if (leftChatId !== undefined && rightChatId !== undefined) {
|
|
142
|
+
return leftChatId === rightChatId;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function consumePendingOutboundMessageId(params: {
|
|
149
|
+
accountId: string;
|
|
150
|
+
chatGuid?: string;
|
|
151
|
+
chatIdentifier?: string;
|
|
152
|
+
chatId?: number;
|
|
153
|
+
body: string;
|
|
154
|
+
}): PendingOutboundMessageId | null {
|
|
155
|
+
prunePendingOutboundMessageIds();
|
|
156
|
+
const bodyNorm = normalizeSnippet(params.body);
|
|
157
|
+
const isMediaBody = params.body.trim().toLowerCase().startsWith("<media:");
|
|
158
|
+
|
|
159
|
+
for (let i = 0; i < pendingOutboundMessageIds.length; i++) {
|
|
160
|
+
const entry = pendingOutboundMessageIds[i];
|
|
161
|
+
if (entry.accountId !== params.accountId) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (!chatsMatch(entry, params)) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (entry.snippetNorm && entry.snippetNorm === bodyNorm) {
|
|
168
|
+
pendingOutboundMessageIds.splice(i, 1);
|
|
169
|
+
return entry;
|
|
170
|
+
}
|
|
171
|
+
if (entry.isMediaSnippet && isMediaBody) {
|
|
172
|
+
pendingOutboundMessageIds.splice(i, 1);
|
|
173
|
+
return entry;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
43
179
|
|
|
44
180
|
export function logVerbose(
|
|
45
181
|
core: BlueBubblesCoreRuntime,
|
|
@@ -107,6 +243,178 @@ function resolveBlueBubblesAckReaction(params: {
|
|
|
107
243
|
}
|
|
108
244
|
}
|
|
109
245
|
|
|
246
|
+
/**
|
|
247
|
+
* In-memory rolling history map keyed by account + chat identifier.
|
|
248
|
+
* Populated from incoming messages during the session.
|
|
249
|
+
* API backfill is attempted until one fetch resolves (or retries are exhausted).
|
|
250
|
+
*/
|
|
251
|
+
const chatHistories = new Map<string, HistoryEntry[]>();
|
|
252
|
+
type HistoryBackfillState = {
|
|
253
|
+
attempts: number;
|
|
254
|
+
firstAttemptAt: number;
|
|
255
|
+
nextAttemptAt: number;
|
|
256
|
+
resolved: boolean;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
const historyBackfills = new Map<string, HistoryBackfillState>();
|
|
260
|
+
const HISTORY_BACKFILL_BASE_DELAY_MS = 5_000;
|
|
261
|
+
const HISTORY_BACKFILL_MAX_DELAY_MS = 2 * 60 * 1000;
|
|
262
|
+
const HISTORY_BACKFILL_MAX_ATTEMPTS = 6;
|
|
263
|
+
const HISTORY_BACKFILL_RETRY_WINDOW_MS = 30 * 60 * 1000;
|
|
264
|
+
const MAX_STORED_HISTORY_ENTRY_CHARS = 2_000;
|
|
265
|
+
const MAX_INBOUND_HISTORY_ENTRY_CHARS = 1_200;
|
|
266
|
+
const MAX_INBOUND_HISTORY_TOTAL_CHARS = 12_000;
|
|
267
|
+
|
|
268
|
+
function buildAccountScopedHistoryKey(accountId: string, historyIdentifier: string): string {
|
|
269
|
+
return `${accountId}\u0000${historyIdentifier}`;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function historyDedupKey(entry: HistoryEntry): string {
|
|
273
|
+
const messageId = entry.messageId?.trim();
|
|
274
|
+
if (messageId) {
|
|
275
|
+
return `id:${messageId}`;
|
|
276
|
+
}
|
|
277
|
+
return `fallback:${entry.sender}\u0000${entry.body}\u0000${entry.timestamp ?? ""}`;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function truncateHistoryBody(body: string, maxChars: number): string {
|
|
281
|
+
const trimmed = body.trim();
|
|
282
|
+
if (!trimmed) {
|
|
283
|
+
return "";
|
|
284
|
+
}
|
|
285
|
+
if (trimmed.length <= maxChars) {
|
|
286
|
+
return trimmed;
|
|
287
|
+
}
|
|
288
|
+
return `${trimmed.slice(0, maxChars).trimEnd()}...`;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function mergeHistoryEntries(params: {
|
|
292
|
+
apiEntries: HistoryEntry[];
|
|
293
|
+
currentEntries: HistoryEntry[];
|
|
294
|
+
limit: number;
|
|
295
|
+
}): HistoryEntry[] {
|
|
296
|
+
if (params.limit <= 0) {
|
|
297
|
+
return [];
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const merged: HistoryEntry[] = [];
|
|
301
|
+
const seen = new Set<string>();
|
|
302
|
+
const appendUnique = (entry: HistoryEntry) => {
|
|
303
|
+
const key = historyDedupKey(entry);
|
|
304
|
+
if (seen.has(key)) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
seen.add(key);
|
|
308
|
+
merged.push(entry);
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
for (const entry of params.apiEntries) {
|
|
312
|
+
appendUnique(entry);
|
|
313
|
+
}
|
|
314
|
+
for (const entry of params.currentEntries) {
|
|
315
|
+
appendUnique(entry);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
if (merged.length <= params.limit) {
|
|
319
|
+
return merged;
|
|
320
|
+
}
|
|
321
|
+
return merged.slice(merged.length - params.limit);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function pruneHistoryBackfillState(): void {
|
|
325
|
+
for (const key of historyBackfills.keys()) {
|
|
326
|
+
if (!chatHistories.has(key)) {
|
|
327
|
+
historyBackfills.delete(key);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function markHistoryBackfillResolved(historyKey: string): void {
|
|
333
|
+
const state = historyBackfills.get(historyKey);
|
|
334
|
+
if (state) {
|
|
335
|
+
state.resolved = true;
|
|
336
|
+
historyBackfills.set(historyKey, state);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
historyBackfills.set(historyKey, {
|
|
340
|
+
attempts: 0,
|
|
341
|
+
firstAttemptAt: Date.now(),
|
|
342
|
+
nextAttemptAt: Number.POSITIVE_INFINITY,
|
|
343
|
+
resolved: true,
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function planHistoryBackfillAttempt(historyKey: string, now: number): HistoryBackfillState | null {
|
|
348
|
+
const existing = historyBackfills.get(historyKey);
|
|
349
|
+
if (existing?.resolved) {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
if (existing && now - existing.firstAttemptAt > HISTORY_BACKFILL_RETRY_WINDOW_MS) {
|
|
353
|
+
markHistoryBackfillResolved(historyKey);
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
if (existing && existing.attempts >= HISTORY_BACKFILL_MAX_ATTEMPTS) {
|
|
357
|
+
markHistoryBackfillResolved(historyKey);
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
if (existing && now < existing.nextAttemptAt) {
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
const attempts = (existing?.attempts ?? 0) + 1;
|
|
365
|
+
const firstAttemptAt = existing?.firstAttemptAt ?? now;
|
|
366
|
+
const backoffDelay = Math.min(
|
|
367
|
+
HISTORY_BACKFILL_BASE_DELAY_MS * 2 ** (attempts - 1),
|
|
368
|
+
HISTORY_BACKFILL_MAX_DELAY_MS,
|
|
369
|
+
);
|
|
370
|
+
const state: HistoryBackfillState = {
|
|
371
|
+
attempts,
|
|
372
|
+
firstAttemptAt,
|
|
373
|
+
nextAttemptAt: now + backoffDelay,
|
|
374
|
+
resolved: false,
|
|
375
|
+
};
|
|
376
|
+
historyBackfills.set(historyKey, state);
|
|
377
|
+
return state;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function buildInboundHistorySnapshot(params: {
|
|
381
|
+
entries: HistoryEntry[];
|
|
382
|
+
limit: number;
|
|
383
|
+
}): Array<{ sender: string; body: string; timestamp?: number }> | undefined {
|
|
384
|
+
if (params.limit <= 0 || params.entries.length === 0) {
|
|
385
|
+
return undefined;
|
|
386
|
+
}
|
|
387
|
+
const recent = params.entries.slice(-params.limit);
|
|
388
|
+
const selected: Array<{ sender: string; body: string; timestamp?: number }> = [];
|
|
389
|
+
let remainingChars = MAX_INBOUND_HISTORY_TOTAL_CHARS;
|
|
390
|
+
|
|
391
|
+
for (let i = recent.length - 1; i >= 0; i--) {
|
|
392
|
+
const entry = recent[i];
|
|
393
|
+
const body = truncateHistoryBody(entry.body, MAX_INBOUND_HISTORY_ENTRY_CHARS);
|
|
394
|
+
if (!body) {
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
if (selected.length > 0 && body.length > remainingChars) {
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
selected.push({
|
|
401
|
+
sender: entry.sender,
|
|
402
|
+
body,
|
|
403
|
+
timestamp: entry.timestamp,
|
|
404
|
+
});
|
|
405
|
+
remainingChars -= body.length;
|
|
406
|
+
if (remainingChars <= 0) {
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (selected.length === 0) {
|
|
412
|
+
return undefined;
|
|
413
|
+
}
|
|
414
|
+
selected.reverse();
|
|
415
|
+
return selected;
|
|
416
|
+
}
|
|
417
|
+
|
|
110
418
|
export async function processMessage(
|
|
111
419
|
message: NormalizedWebhookMessage,
|
|
112
420
|
target: WebhookTarget,
|
|
@@ -158,6 +466,26 @@ export async function processMessage(
|
|
|
158
466
|
if (message.fromMe) {
|
|
159
467
|
// Cache from-me messages so reply context can resolve sender/body.
|
|
160
468
|
cacheInboundMessage();
|
|
469
|
+
if (cacheMessageId) {
|
|
470
|
+
const pending = consumePendingOutboundMessageId({
|
|
471
|
+
accountId: account.accountId,
|
|
472
|
+
chatGuid: message.chatGuid,
|
|
473
|
+
chatIdentifier: message.chatIdentifier,
|
|
474
|
+
chatId: message.chatId,
|
|
475
|
+
body: rawBody,
|
|
476
|
+
});
|
|
477
|
+
if (pending) {
|
|
478
|
+
const displayId = getShortIdForUuid(cacheMessageId) || cacheMessageId;
|
|
479
|
+
const previewSource = pending.snippetRaw || rawBody;
|
|
480
|
+
const preview = previewSource
|
|
481
|
+
? ` "${previewSource.slice(0, 12)}${previewSource.length > 12 ? "…" : ""}"`
|
|
482
|
+
: "";
|
|
483
|
+
core.system.enqueueSystemEvent(`Assistant sent${preview} [message_id:${displayId}]`, {
|
|
484
|
+
sessionKey: pending.sessionKey,
|
|
485
|
+
contextKey: `bluebubbles:outbound:${pending.outboundTarget}:${cacheMessageId}`,
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}
|
|
161
489
|
return;
|
|
162
490
|
}
|
|
163
491
|
|
|
@@ -173,41 +501,51 @@ export async function processMessage(
|
|
|
173
501
|
|
|
174
502
|
const dmPolicy = account.config.dmPolicy ?? "pairing";
|
|
175
503
|
const groupPolicy = account.config.groupPolicy ?? "allowlist";
|
|
176
|
-
const configAllowFrom = (account.config.allowFrom ?? []).map((entry) => String(entry));
|
|
177
|
-
const configGroupAllowFrom = (account.config.groupAllowFrom ?? []).map((entry) => String(entry));
|
|
178
504
|
const storeAllowFrom = await core.channel.pairing
|
|
179
505
|
.readAllowFromStore("bluebubbles")
|
|
180
506
|
.catch(() => []);
|
|
181
|
-
const effectiveAllowFrom =
|
|
182
|
-
|
|
183
|
-
.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
]
|
|
188
|
-
.map((entry) => String(entry).trim())
|
|
189
|
-
.filter(Boolean);
|
|
507
|
+
const { effectiveAllowFrom, effectiveGroupAllowFrom } = resolveEffectiveAllowFromLists({
|
|
508
|
+
allowFrom: account.config.allowFrom,
|
|
509
|
+
groupAllowFrom: account.config.groupAllowFrom,
|
|
510
|
+
storeAllowFrom,
|
|
511
|
+
dmPolicy,
|
|
512
|
+
});
|
|
190
513
|
const groupAllowEntry = formatGroupAllowlistEntry({
|
|
191
514
|
chatGuid: message.chatGuid,
|
|
192
515
|
chatId: message.chatId ?? undefined,
|
|
193
516
|
chatIdentifier: message.chatIdentifier ?? undefined,
|
|
194
517
|
});
|
|
195
518
|
const groupName = message.chatName?.trim() || undefined;
|
|
519
|
+
const accessDecision = resolveDmGroupAccessDecision({
|
|
520
|
+
isGroup,
|
|
521
|
+
dmPolicy,
|
|
522
|
+
groupPolicy,
|
|
523
|
+
effectiveAllowFrom,
|
|
524
|
+
effectiveGroupAllowFrom,
|
|
525
|
+
isSenderAllowed: (allowFrom) =>
|
|
526
|
+
isAllowedBlueBubblesSender({
|
|
527
|
+
allowFrom,
|
|
528
|
+
sender: message.senderId,
|
|
529
|
+
chatId: message.chatId ?? undefined,
|
|
530
|
+
chatGuid: message.chatGuid ?? undefined,
|
|
531
|
+
chatIdentifier: message.chatIdentifier ?? undefined,
|
|
532
|
+
}),
|
|
533
|
+
});
|
|
196
534
|
|
|
197
|
-
if (
|
|
198
|
-
if (
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if (
|
|
535
|
+
if (accessDecision.decision !== "allow") {
|
|
536
|
+
if (isGroup) {
|
|
537
|
+
if (accessDecision.reason === "groupPolicy=disabled") {
|
|
538
|
+
logVerbose(core, runtime, "Blocked BlueBubbles group message (groupPolicy=disabled)");
|
|
539
|
+
logGroupAllowlistHint({
|
|
540
|
+
runtime,
|
|
541
|
+
reason: "groupPolicy=disabled",
|
|
542
|
+
entry: groupAllowEntry,
|
|
543
|
+
chatName: groupName,
|
|
544
|
+
accountId: account.accountId,
|
|
545
|
+
});
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
if (accessDecision.reason === "groupPolicy=allowlist (empty allowlist)") {
|
|
211
549
|
logVerbose(core, runtime, "Blocked BlueBubbles group message (no allowlist)");
|
|
212
550
|
logGroupAllowlistHint({
|
|
213
551
|
runtime,
|
|
@@ -218,14 +556,7 @@ export async function processMessage(
|
|
|
218
556
|
});
|
|
219
557
|
return;
|
|
220
558
|
}
|
|
221
|
-
|
|
222
|
-
allowFrom: effectiveGroupAllowFrom,
|
|
223
|
-
sender: message.senderId,
|
|
224
|
-
chatId: message.chatId ?? undefined,
|
|
225
|
-
chatGuid: message.chatGuid ?? undefined,
|
|
226
|
-
chatIdentifier: message.chatIdentifier ?? undefined,
|
|
227
|
-
});
|
|
228
|
-
if (!allowed) {
|
|
559
|
+
if (accessDecision.reason === "groupPolicy=allowlist (not allowlisted)") {
|
|
229
560
|
logVerbose(
|
|
230
561
|
core,
|
|
231
562
|
runtime,
|
|
@@ -245,70 +576,60 @@ export async function processMessage(
|
|
|
245
576
|
});
|
|
246
577
|
return;
|
|
247
578
|
}
|
|
579
|
+
return;
|
|
248
580
|
}
|
|
249
|
-
|
|
250
|
-
if (
|
|
581
|
+
|
|
582
|
+
if (accessDecision.reason === "dmPolicy=disabled") {
|
|
251
583
|
logVerbose(core, runtime, `Blocked BlueBubbles DM from ${message.senderId}`);
|
|
252
584
|
logVerbose(core, runtime, `drop: dmPolicy disabled sender=${message.senderId}`);
|
|
253
585
|
return;
|
|
254
586
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
chatIdentifier: message.chatIdentifier ?? undefined,
|
|
587
|
+
|
|
588
|
+
if (accessDecision.decision === "pairing") {
|
|
589
|
+
const { code, created } = await core.channel.pairing.upsertPairingRequest({
|
|
590
|
+
channel: "bluebubbles",
|
|
591
|
+
id: message.senderId,
|
|
592
|
+
meta: { name: message.senderName },
|
|
262
593
|
});
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
594
|
+
runtime.log?.(`[bluebubbles] pairing request sender=${message.senderId} created=${created}`);
|
|
595
|
+
if (created) {
|
|
596
|
+
logVerbose(core, runtime, `bluebubbles pairing request sender=${message.senderId}`);
|
|
597
|
+
try {
|
|
598
|
+
await sendMessageBlueBubbles(
|
|
599
|
+
message.senderId,
|
|
600
|
+
core.channel.pairing.buildPairingReply({
|
|
601
|
+
channel: "bluebubbles",
|
|
602
|
+
idLine: `Your BlueBubbles sender id: ${message.senderId}`,
|
|
603
|
+
code,
|
|
604
|
+
}),
|
|
605
|
+
{ cfg: config, accountId: account.accountId },
|
|
272
606
|
);
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
try {
|
|
276
|
-
await sendMessageBlueBubbles(
|
|
277
|
-
message.senderId,
|
|
278
|
-
core.channel.pairing.buildPairingReply({
|
|
279
|
-
channel: "bluebubbles",
|
|
280
|
-
idLine: `Your BlueBubbles sender id: ${message.senderId}`,
|
|
281
|
-
code,
|
|
282
|
-
}),
|
|
283
|
-
{ cfg: config, accountId: account.accountId },
|
|
284
|
-
);
|
|
285
|
-
statusSink?.({ lastOutboundAt: Date.now() });
|
|
286
|
-
} catch (err) {
|
|
287
|
-
logVerbose(
|
|
288
|
-
core,
|
|
289
|
-
runtime,
|
|
290
|
-
`bluebubbles pairing reply failed for ${message.senderId}: ${String(err)}`,
|
|
291
|
-
);
|
|
292
|
-
runtime.error?.(
|
|
293
|
-
`[bluebubbles] pairing reply failed sender=${message.senderId}: ${String(err)}`,
|
|
294
|
-
);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
} else {
|
|
607
|
+
statusSink?.({ lastOutboundAt: Date.now() });
|
|
608
|
+
} catch (err) {
|
|
298
609
|
logVerbose(
|
|
299
610
|
core,
|
|
300
611
|
runtime,
|
|
301
|
-
`
|
|
612
|
+
`bluebubbles pairing reply failed for ${message.senderId}: ${String(err)}`,
|
|
302
613
|
);
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
runtime,
|
|
306
|
-
`drop: dm sender not allowed sender=${message.senderId} allowFrom=${effectiveAllowFrom.join(",")}`,
|
|
614
|
+
runtime.error?.(
|
|
615
|
+
`[bluebubbles] pairing reply failed sender=${message.senderId}: ${String(err)}`,
|
|
307
616
|
);
|
|
308
617
|
}
|
|
309
|
-
return;
|
|
310
618
|
}
|
|
619
|
+
return;
|
|
311
620
|
}
|
|
621
|
+
|
|
622
|
+
logVerbose(
|
|
623
|
+
core,
|
|
624
|
+
runtime,
|
|
625
|
+
`Blocked unauthorized BlueBubbles sender ${message.senderId} (dmPolicy=${dmPolicy})`,
|
|
626
|
+
);
|
|
627
|
+
logVerbose(
|
|
628
|
+
core,
|
|
629
|
+
runtime,
|
|
630
|
+
`drop: dm sender not allowed sender=${message.senderId} allowFrom=${effectiveAllowFrom.join(",")}`,
|
|
631
|
+
);
|
|
632
|
+
return;
|
|
312
633
|
}
|
|
313
634
|
|
|
314
635
|
const chatId = message.chatId ?? undefined;
|
|
@@ -629,10 +950,10 @@ export async function processMessage(
|
|
|
629
950
|
? formatBlueBubblesChatTarget({ chatGuid: chatGuidForActions })
|
|
630
951
|
: message.senderId;
|
|
631
952
|
|
|
632
|
-
const maybeEnqueueOutboundMessageId = (messageId?: string, snippet?: string) => {
|
|
953
|
+
const maybeEnqueueOutboundMessageId = (messageId?: string, snippet?: string): boolean => {
|
|
633
954
|
const trimmed = messageId?.trim();
|
|
634
955
|
if (!trimmed || trimmed === "ok" || trimmed === "unknown") {
|
|
635
|
-
return;
|
|
956
|
+
return false;
|
|
636
957
|
}
|
|
637
958
|
// Cache outbound message to get short ID
|
|
638
959
|
const cacheEntry = rememberBlueBubblesReplyCache({
|
|
@@ -651,6 +972,7 @@ export async function processMessage(
|
|
|
651
972
|
sessionKey: route.sessionKey,
|
|
652
973
|
contextKey: `bluebubbles:outbound:${outboundTarget}:${trimmed}`,
|
|
653
974
|
});
|
|
975
|
+
return true;
|
|
654
976
|
};
|
|
655
977
|
const sanitizeReplyDirectiveText = (value: string): string => {
|
|
656
978
|
if (privateApiEnabled) {
|
|
@@ -662,9 +984,118 @@ export async function processMessage(
|
|
|
662
984
|
.trim();
|
|
663
985
|
};
|
|
664
986
|
|
|
987
|
+
// History: in-memory rolling map with bounded API backfill retries
|
|
988
|
+
const historyLimit = isGroup
|
|
989
|
+
? (account.config.historyLimit ?? 0)
|
|
990
|
+
: (account.config.dmHistoryLimit ?? 0);
|
|
991
|
+
|
|
992
|
+
const historyIdentifier =
|
|
993
|
+
chatGuid ||
|
|
994
|
+
chatIdentifier ||
|
|
995
|
+
(chatId ? String(chatId) : null) ||
|
|
996
|
+
(isGroup ? null : message.senderId) ||
|
|
997
|
+
"";
|
|
998
|
+
const historyKey = historyIdentifier
|
|
999
|
+
? buildAccountScopedHistoryKey(account.accountId, historyIdentifier)
|
|
1000
|
+
: "";
|
|
1001
|
+
|
|
1002
|
+
// Record the current message into rolling history
|
|
1003
|
+
if (historyKey && historyLimit > 0) {
|
|
1004
|
+
const nowMs = Date.now();
|
|
1005
|
+
const senderLabel = message.fromMe ? "me" : message.senderName || message.senderId;
|
|
1006
|
+
const normalizedHistoryBody = truncateHistoryBody(text, MAX_STORED_HISTORY_ENTRY_CHARS);
|
|
1007
|
+
const currentEntries = recordPendingHistoryEntryIfEnabled({
|
|
1008
|
+
historyMap: chatHistories,
|
|
1009
|
+
limit: historyLimit,
|
|
1010
|
+
historyKey,
|
|
1011
|
+
entry: normalizedHistoryBody
|
|
1012
|
+
? {
|
|
1013
|
+
sender: senderLabel,
|
|
1014
|
+
body: normalizedHistoryBody,
|
|
1015
|
+
timestamp: message.timestamp ?? nowMs,
|
|
1016
|
+
messageId: message.messageId ?? undefined,
|
|
1017
|
+
}
|
|
1018
|
+
: null,
|
|
1019
|
+
});
|
|
1020
|
+
pruneHistoryBackfillState();
|
|
1021
|
+
|
|
1022
|
+
const backfillAttempt = planHistoryBackfillAttempt(historyKey, nowMs);
|
|
1023
|
+
if (backfillAttempt) {
|
|
1024
|
+
try {
|
|
1025
|
+
const backfillResult = await fetchBlueBubblesHistory(historyIdentifier, historyLimit, {
|
|
1026
|
+
cfg: config,
|
|
1027
|
+
accountId: account.accountId,
|
|
1028
|
+
});
|
|
1029
|
+
if (backfillResult.resolved) {
|
|
1030
|
+
markHistoryBackfillResolved(historyKey);
|
|
1031
|
+
}
|
|
1032
|
+
if (backfillResult.entries.length > 0) {
|
|
1033
|
+
const apiEntries: HistoryEntry[] = [];
|
|
1034
|
+
for (const entry of backfillResult.entries) {
|
|
1035
|
+
const body = truncateHistoryBody(entry.body, MAX_STORED_HISTORY_ENTRY_CHARS);
|
|
1036
|
+
if (!body) {
|
|
1037
|
+
continue;
|
|
1038
|
+
}
|
|
1039
|
+
apiEntries.push({
|
|
1040
|
+
sender: entry.sender,
|
|
1041
|
+
body,
|
|
1042
|
+
timestamp: entry.timestamp,
|
|
1043
|
+
messageId: entry.messageId,
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
const merged = mergeHistoryEntries({
|
|
1047
|
+
apiEntries,
|
|
1048
|
+
currentEntries:
|
|
1049
|
+
currentEntries.length > 0 ? currentEntries : (chatHistories.get(historyKey) ?? []),
|
|
1050
|
+
limit: historyLimit,
|
|
1051
|
+
});
|
|
1052
|
+
if (chatHistories.has(historyKey)) {
|
|
1053
|
+
chatHistories.delete(historyKey);
|
|
1054
|
+
}
|
|
1055
|
+
chatHistories.set(historyKey, merged);
|
|
1056
|
+
evictOldHistoryKeys(chatHistories);
|
|
1057
|
+
logVerbose(
|
|
1058
|
+
core,
|
|
1059
|
+
runtime,
|
|
1060
|
+
`backfilled ${backfillResult.entries.length} history messages for ${isGroup ? "group" : "DM"}: ${historyIdentifier}`,
|
|
1061
|
+
);
|
|
1062
|
+
} else if (!backfillResult.resolved) {
|
|
1063
|
+
const remainingAttempts = HISTORY_BACKFILL_MAX_ATTEMPTS - backfillAttempt.attempts;
|
|
1064
|
+
const nextBackoffMs = Math.max(backfillAttempt.nextAttemptAt - nowMs, 0);
|
|
1065
|
+
logVerbose(
|
|
1066
|
+
core,
|
|
1067
|
+
runtime,
|
|
1068
|
+
`history backfill unresolved for ${historyIdentifier}; retries left=${Math.max(remainingAttempts, 0)} next_in_ms=${nextBackoffMs}`,
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
} catch (err) {
|
|
1072
|
+
const remainingAttempts = HISTORY_BACKFILL_MAX_ATTEMPTS - backfillAttempt.attempts;
|
|
1073
|
+
const nextBackoffMs = Math.max(backfillAttempt.nextAttemptAt - nowMs, 0);
|
|
1074
|
+
logVerbose(
|
|
1075
|
+
core,
|
|
1076
|
+
runtime,
|
|
1077
|
+
`history backfill failed for ${historyIdentifier}: ${String(err)} (retries left=${Math.max(remainingAttempts, 0)} next_in_ms=${nextBackoffMs})`,
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// Build inbound history from the in-memory map
|
|
1084
|
+
let inboundHistory: Array<{ sender: string; body: string; timestamp?: number }> | undefined;
|
|
1085
|
+
if (historyKey && historyLimit > 0) {
|
|
1086
|
+
const entries = chatHistories.get(historyKey);
|
|
1087
|
+
if (entries && entries.length > 0) {
|
|
1088
|
+
inboundHistory = buildInboundHistorySnapshot({
|
|
1089
|
+
entries,
|
|
1090
|
+
limit: historyLimit,
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
|
|
665
1095
|
const ctxPayload = core.channel.reply.finalizeInboundContext({
|
|
666
1096
|
Body: body,
|
|
667
1097
|
BodyForAgent: rawBody,
|
|
1098
|
+
InboundHistory: inboundHistory,
|
|
668
1099
|
RawBody: rawBody,
|
|
669
1100
|
CommandBody: rawBody,
|
|
670
1101
|
BodyForCommands: rawBody,
|
|
@@ -768,16 +1199,33 @@ export async function processMessage(
|
|
|
768
1199
|
for (const mediaUrl of mediaList) {
|
|
769
1200
|
const caption = first ? text : undefined;
|
|
770
1201
|
first = false;
|
|
771
|
-
const
|
|
772
|
-
|
|
773
|
-
to: outboundTarget,
|
|
774
|
-
mediaUrl,
|
|
775
|
-
caption: caption ?? undefined,
|
|
776
|
-
replyToId: replyToMessageGuid || null,
|
|
1202
|
+
const cachedBody = (caption ?? "").trim() || "<media:attachment>";
|
|
1203
|
+
const pendingId = rememberPendingOutboundMessageId({
|
|
777
1204
|
accountId: account.accountId,
|
|
1205
|
+
sessionKey: route.sessionKey,
|
|
1206
|
+
outboundTarget,
|
|
1207
|
+
chatGuid: chatGuidForActions ?? chatGuid,
|
|
1208
|
+
chatIdentifier,
|
|
1209
|
+
chatId,
|
|
1210
|
+
snippet: cachedBody,
|
|
778
1211
|
});
|
|
779
|
-
|
|
780
|
-
|
|
1212
|
+
let result: Awaited<ReturnType<typeof sendBlueBubblesMedia>>;
|
|
1213
|
+
try {
|
|
1214
|
+
result = await sendBlueBubblesMedia({
|
|
1215
|
+
cfg: config,
|
|
1216
|
+
to: outboundTarget,
|
|
1217
|
+
mediaUrl,
|
|
1218
|
+
caption: caption ?? undefined,
|
|
1219
|
+
replyToId: replyToMessageGuid || null,
|
|
1220
|
+
accountId: account.accountId,
|
|
1221
|
+
});
|
|
1222
|
+
} catch (err) {
|
|
1223
|
+
forgetPendingOutboundMessageId(pendingId);
|
|
1224
|
+
throw err;
|
|
1225
|
+
}
|
|
1226
|
+
if (maybeEnqueueOutboundMessageId(result.messageId, cachedBody)) {
|
|
1227
|
+
forgetPendingOutboundMessageId(pendingId);
|
|
1228
|
+
}
|
|
781
1229
|
sentMessage = true;
|
|
782
1230
|
statusSink?.({ lastOutboundAt: Date.now() });
|
|
783
1231
|
if (info.kind === "block") {
|
|
@@ -811,12 +1259,29 @@ export async function processMessage(
|
|
|
811
1259
|
return;
|
|
812
1260
|
}
|
|
813
1261
|
for (const chunk of chunks) {
|
|
814
|
-
const
|
|
815
|
-
cfg: config,
|
|
1262
|
+
const pendingId = rememberPendingOutboundMessageId({
|
|
816
1263
|
accountId: account.accountId,
|
|
817
|
-
|
|
1264
|
+
sessionKey: route.sessionKey,
|
|
1265
|
+
outboundTarget,
|
|
1266
|
+
chatGuid: chatGuidForActions ?? chatGuid,
|
|
1267
|
+
chatIdentifier,
|
|
1268
|
+
chatId,
|
|
1269
|
+
snippet: chunk,
|
|
818
1270
|
});
|
|
819
|
-
|
|
1271
|
+
let result: Awaited<ReturnType<typeof sendMessageBlueBubbles>>;
|
|
1272
|
+
try {
|
|
1273
|
+
result = await sendMessageBlueBubbles(outboundTarget, chunk, {
|
|
1274
|
+
cfg: config,
|
|
1275
|
+
accountId: account.accountId,
|
|
1276
|
+
replyToMessageGuid: replyToMessageGuid || undefined,
|
|
1277
|
+
});
|
|
1278
|
+
} catch (err) {
|
|
1279
|
+
forgetPendingOutboundMessageId(pendingId);
|
|
1280
|
+
throw err;
|
|
1281
|
+
}
|
|
1282
|
+
if (maybeEnqueueOutboundMessageId(result.messageId, chunk)) {
|
|
1283
|
+
forgetPendingOutboundMessageId(pendingId);
|
|
1284
|
+
}
|
|
820
1285
|
sentMessage = true;
|
|
821
1286
|
statusSink?.({ lastOutboundAt: Date.now() });
|
|
822
1287
|
if (info.kind === "block") {
|
|
@@ -921,56 +1386,32 @@ export async function processReaction(
|
|
|
921
1386
|
|
|
922
1387
|
const dmPolicy = account.config.dmPolicy ?? "pairing";
|
|
923
1388
|
const groupPolicy = account.config.groupPolicy ?? "allowlist";
|
|
924
|
-
const configAllowFrom = (account.config.allowFrom ?? []).map((entry) => String(entry));
|
|
925
|
-
const configGroupAllowFrom = (account.config.groupAllowFrom ?? []).map((entry) => String(entry));
|
|
926
1389
|
const storeAllowFrom = await core.channel.pairing
|
|
927
1390
|
.readAllowFromStore("bluebubbles")
|
|
928
1391
|
.catch(() => []);
|
|
929
|
-
const effectiveAllowFrom =
|
|
930
|
-
|
|
931
|
-
.
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
if (effectiveGroupAllowFrom.length === 0) {
|
|
945
|
-
return;
|
|
946
|
-
}
|
|
947
|
-
const allowed = isAllowedBlueBubblesSender({
|
|
948
|
-
allowFrom: effectiveGroupAllowFrom,
|
|
949
|
-
sender: reaction.senderId,
|
|
950
|
-
chatId: reaction.chatId ?? undefined,
|
|
951
|
-
chatGuid: reaction.chatGuid ?? undefined,
|
|
952
|
-
chatIdentifier: reaction.chatIdentifier ?? undefined,
|
|
953
|
-
});
|
|
954
|
-
if (!allowed) {
|
|
955
|
-
return;
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
} else {
|
|
959
|
-
if (dmPolicy === "disabled") {
|
|
960
|
-
return;
|
|
961
|
-
}
|
|
962
|
-
if (dmPolicy !== "open") {
|
|
963
|
-
const allowed = isAllowedBlueBubblesSender({
|
|
964
|
-
allowFrom: effectiveAllowFrom,
|
|
1392
|
+
const { effectiveAllowFrom, effectiveGroupAllowFrom } = resolveEffectiveAllowFromLists({
|
|
1393
|
+
allowFrom: account.config.allowFrom,
|
|
1394
|
+
groupAllowFrom: account.config.groupAllowFrom,
|
|
1395
|
+
storeAllowFrom,
|
|
1396
|
+
dmPolicy,
|
|
1397
|
+
});
|
|
1398
|
+
const accessDecision = resolveDmGroupAccessDecision({
|
|
1399
|
+
isGroup: reaction.isGroup,
|
|
1400
|
+
dmPolicy,
|
|
1401
|
+
groupPolicy,
|
|
1402
|
+
effectiveAllowFrom,
|
|
1403
|
+
effectiveGroupAllowFrom,
|
|
1404
|
+
isSenderAllowed: (allowFrom) =>
|
|
1405
|
+
isAllowedBlueBubblesSender({
|
|
1406
|
+
allowFrom,
|
|
965
1407
|
sender: reaction.senderId,
|
|
966
1408
|
chatId: reaction.chatId ?? undefined,
|
|
967
1409
|
chatGuid: reaction.chatGuid ?? undefined,
|
|
968
1410
|
chatIdentifier: reaction.chatIdentifier ?? undefined,
|
|
969
|
-
})
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
}
|
|
1411
|
+
}),
|
|
1412
|
+
});
|
|
1413
|
+
if (accessDecision.decision !== "allow") {
|
|
1414
|
+
return;
|
|
974
1415
|
}
|
|
975
1416
|
|
|
976
1417
|
const chatId = reaction.chatId ?? undefined;
|