@poolzin/pool-bot 2026.2.11 → 2026.2.18
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/CHANGELOG.md +34 -0
- package/dist/agents/agent-scope.js +4 -0
- package/dist/agents/announce-idempotency.js +14 -0
- package/dist/agents/auth-profiles/usage.js +22 -0
- package/dist/agents/auth-profiles.js +1 -1
- package/dist/agents/auth-profiles.resolve-auth-profile-order.fixtures.js +23 -0
- package/dist/agents/bash-tools.exec-runtime.js +438 -0
- package/dist/agents/bash-tools.shared.js +6 -0
- package/dist/agents/cli-runner/reliability.js +61 -0
- package/dist/agents/cli-watchdog-defaults.js +11 -0
- package/dist/agents/command-poll-backoff.js +63 -0
- package/dist/agents/current-time.js +16 -0
- package/dist/agents/glob-pattern.js +42 -0
- package/dist/agents/memory-search.js +33 -0
- package/dist/agents/model-alias-lines.js +18 -0
- package/dist/agents/model-auth-label.js +61 -0
- package/dist/agents/model-fallback.js +59 -8
- package/dist/agents/models-config.e2e-harness.js +115 -0
- package/dist/agents/ollama-stream.js +11 -3
- package/dist/agents/openclaw-tools.js +135 -0
- package/dist/agents/pi-auth-json.js +118 -0
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +147 -0
- package/dist/agents/pi-embedded-subscribe.e2e-harness.js +90 -0
- package/dist/agents/pi-embedded-subscribe.handlers.compaction.js +63 -0
- package/dist/agents/pi-embedded-subscribe.handlers.tools.media.test-helpers.js +30 -0
- package/dist/agents/pi-extensions/session-manager-runtime-registry.js +23 -0
- package/dist/agents/pi-tools.before-tool-call.js +145 -4
- package/dist/agents/pi-tools.js +29 -9
- package/dist/agents/pi-tools.policy.js +85 -92
- package/dist/agents/pi-tools.schema.js +54 -27
- package/dist/agents/queued-file-writer.js +22 -0
- package/dist/agents/sandbox/docker.js +133 -40
- package/dist/agents/sandbox/fs-bridge.js +146 -0
- package/dist/agents/sandbox/fs-paths.js +205 -0
- package/dist/agents/sandbox/hash.js +4 -0
- package/dist/agents/sandbox/validate-sandbox-security.js +157 -0
- package/dist/agents/sandbox-paths.js +3 -0
- package/dist/agents/sandbox-tool-policy.js +26 -0
- package/dist/agents/sanitize-for-prompt.js +18 -0
- package/dist/agents/session-dirs.js +20 -0
- package/dist/agents/session-write-lock.js +203 -39
- package/dist/agents/skills/filter.js +24 -0
- package/dist/agents/skills/tools-dir.js +9 -0
- package/dist/agents/skills-install-download.js +290 -0
- package/dist/agents/skills-install-output.js +30 -0
- package/dist/agents/skills-install.download-test-utils.js +36 -0
- package/dist/agents/skills.e2e-test-helpers.js +13 -0
- package/dist/agents/subagent-announce-queue.js +59 -15
- package/dist/agents/subagent-depth.js +137 -0
- package/dist/agents/subagent-registry.js +448 -96
- package/dist/agents/subagent-spawn.js +262 -0
- package/dist/agents/system-prompt.js +52 -10
- package/dist/agents/test-helpers/fast-tool-stubs.js +18 -0
- package/dist/agents/test-helpers/host-sandbox-fs-bridge.js +74 -0
- package/dist/agents/tool-display-common.js +782 -0
- package/dist/agents/tool-loop-detection.js +466 -0
- package/dist/agents/tool-policy.js +6 -0
- package/dist/agents/tools/image-tool.js +1 -1
- package/dist/agents/tools/sessions-access.js +178 -0
- package/dist/agents/tools/sessions-resolution.js +206 -0
- package/dist/agents/tools/subagents-tool.js +616 -0
- package/dist/agents/workspace-dir.js +18 -0
- package/dist/agents/workspace-dirs.js +14 -0
- package/dist/agents/workspace.js +70 -0
- package/dist/auto-reply/heartbeat-reply-payload.js +18 -0
- package/dist/auto-reply/reply/commands-export-session.js +163 -0
- package/dist/auto-reply/reply/commands-mesh.js +245 -0
- package/dist/auto-reply/reply/commands-setunset.js +28 -0
- package/dist/auto-reply/reply/commands-slash-parse.js +31 -0
- package/dist/auto-reply/reply/commands-system-prompt.js +117 -0
- package/dist/auto-reply/reply/directive-handling.levels.js +17 -0
- package/dist/auto-reply/reply/directive-handling.params.js +1 -0
- package/dist/auto-reply/reply/directive-parsing.js +36 -0
- package/dist/auto-reply/reply/dispatcher-registry.js +43 -0
- package/dist/auto-reply/reply/elevated-unavailable.js +20 -0
- package/dist/auto-reply/reply/post-compaction-audit.js +96 -0
- package/dist/auto-reply/reply/post-compaction-context.js +98 -0
- package/dist/auto-reply/reply/reply-delivery.js +92 -0
- package/dist/auto-reply/reply/session-reset-prompt.js +1 -0
- package/dist/auto-reply/reply/session-run-accounting.js +33 -0
- package/dist/auto-reply/reply.directive.directive-behavior.e2e-harness.js +115 -0
- package/dist/auto-reply/reply.directive.directive-behavior.e2e-mocks.js +12 -0
- package/dist/browser/bridge-auth-registry.js +26 -0
- package/dist/browser/client-actions-url.js +10 -0
- package/dist/browser/control-auth.js +73 -0
- package/dist/browser/csrf.js +64 -0
- package/dist/browser/http-auth.js +52 -0
- package/dist/browser/paths.js +37 -0
- package/dist/browser/proxy-files.js +32 -0
- package/dist/browser/pw-ai-state.js +7 -0
- package/dist/browser/resolved-config-refresh.js +42 -0
- package/dist/browser/routes/path-output.js +1 -0
- package/dist/browser/server-context.chrome-test-harness.js +20 -0
- package/dist/browser/server-middleware.js +31 -0
- package/dist/browser/test-port.js +16 -0
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/file-resolver.js +43 -0
- package/dist/channels/account-summary.js +19 -0
- package/dist/channels/draft-stream-loop.js +77 -0
- package/dist/channels/plugins/account-helpers.js +26 -0
- package/dist/channels/telegram/allow-from.js +10 -0
- package/dist/cli/browser-cli-resize.js +22 -0
- package/dist/cli/browser-cli-shared.js +8 -0
- package/dist/cli/clawbot-cli.js +5 -0
- package/dist/cli/completion-cli.js +566 -0
- package/dist/cli/config-cli.js +63 -5
- package/dist/cli/daemon-cli/lifecycle-core.js +256 -0
- package/dist/cli/daemon-cli/register-service-commands.js +60 -0
- package/dist/cli/daemon-cli-compat.js +80 -0
- package/dist/cli/nodes-cli/pairing-render.js +26 -0
- package/dist/cli/program/action-reparse.js +17 -0
- package/dist/cli/program/command-registry.js +17 -0
- package/dist/cli/program/program-context.js +8 -0
- package/dist/cli/program/register.subclis.js +7 -0
- package/dist/cli/program/routes.js +233 -0
- package/dist/cli/qr-cli.js +132 -0
- package/dist/cli/requirements-test-fixtures.js +17 -0
- package/dist/cli/respawn-policy.js +4 -0
- package/dist/cli/shared/parse-port.js +18 -0
- package/dist/cli/skills-cli.format.js +241 -0
- package/dist/cli/update-cli/progress.js +121 -0
- package/dist/cli/update-cli/restart-helper.js +108 -0
- package/dist/cli/update-cli/shared.js +196 -0
- package/dist/cli/update-cli/status.js +97 -0
- package/dist/cli/update-cli/suppress-deprecations.js +17 -0
- package/dist/cli/update-cli/update-command.js +506 -0
- package/dist/cli/update-cli/wizard.js +130 -0
- package/dist/cli/update-cli.js +3 -9
- package/dist/cli/windows-argv.js +69 -0
- package/dist/commands/auth-choice-legacy.js +20 -0
- package/dist/commands/auth-choice.apply-helpers.js +8 -0
- package/dist/commands/channel-test-helpers.js +19 -0
- package/dist/commands/cleanup-plan.js +10 -0
- package/dist/commands/cleanup-utils.js +7 -0
- package/dist/commands/config-validation.js +15 -0
- package/dist/commands/doctor-completion.js +112 -0
- package/dist/commands/doctor-memory-search.js +119 -0
- package/dist/commands/doctor-session-locks.js +73 -0
- package/dist/commands/doctor.e2e-harness.js +364 -0
- package/dist/commands/gateway-presence.js +19 -0
- package/dist/commands/model-default.js +35 -0
- package/dist/commands/models/fallbacks-shared.js +102 -0
- package/dist/commands/models/shared.js +24 -0
- package/dist/commands/onboard-auth.config-gateways.js +64 -0
- package/dist/commands/onboard-auth.config-litellm.js +45 -0
- package/dist/commands/onboard-auth.config-shared.js +116 -0
- package/dist/commands/onboard-config.js +16 -0
- package/dist/commands/onboard-non-interactive.test-helpers.js +31 -0
- package/dist/commands/onboard-provider-auth-flags.js +136 -0
- package/dist/commands/openai-codex-oauth.js +40 -0
- package/dist/commands/test-runtime-config-helpers.js +21 -0
- package/dist/commands/test-wizard-helpers.js +68 -0
- package/dist/commands/vllm-setup.js +66 -0
- package/dist/compat/legacy-names.js +2 -0
- package/dist/config/backup-rotation.js +19 -0
- package/dist/config/env-preserve.js +122 -0
- package/dist/config/includes-scan.js +78 -0
- package/dist/config/plugins-allowlist.js +13 -0
- package/dist/config/schema.help.js +256 -0
- package/dist/config/schema.hints.js +189 -0
- package/dist/config/schema.irc.js +20 -0
- package/dist/config/schema.labels.js +317 -0
- package/dist/config/sessions/delivery-info.js +40 -0
- package/dist/config/types.irc.js +1 -0
- package/dist/config/zod-schema.agent-defaults.js +14 -0
- package/dist/config/zod-schema.agent-model.js +10 -0
- package/dist/config/zod-schema.agent-runtime.js +14 -0
- package/dist/config/zod-schema.allowdeny.js +35 -0
- package/dist/config/zod-schema.sensitive.js +4 -0
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
- package/dist/cron/isolated-agent/skills-snapshot.js +26 -0
- package/dist/cron/isolated-agent/subagent-followup.js +127 -0
- package/dist/cron/isolated-agent.mocks.js +12 -0
- package/dist/cron/isolated-agent.test-setup.js +22 -0
- package/dist/cron/legacy-delivery.js +43 -0
- package/dist/cron/webhook-url.js +22 -0
- package/dist/daemon/arg-split.js +40 -0
- package/dist/daemon/exec-file.js +23 -0
- package/dist/daemon/output.js +6 -0
- package/dist/daemon/runtime-format.js +31 -0
- package/dist/daemon/schtasks-exec.js +4 -0
- package/dist/daemon/service-audit.js +22 -0
- package/dist/discord/client.js +41 -0
- package/dist/discord/components-registry.js +57 -0
- package/dist/discord/components.js +816 -0
- package/dist/discord/guilds.js +12 -0
- package/dist/discord/monitor/gateway-plugin.js +48 -0
- package/dist/discord/monitor/presence.js +30 -0
- package/dist/discord/send.components.js +115 -0
- package/dist/discord/send.shared.js +4 -0
- package/dist/discord/ui.js +26 -0
- package/dist/discord/voice-message.js +254 -0
- package/dist/gateway/agent-event-assistant-text.js +5 -0
- package/dist/gateway/agent-prompt.js +33 -0
- package/dist/gateway/auth-rate-limit.js +136 -0
- package/dist/gateway/channel-health-monitor.js +114 -0
- package/dist/gateway/control-ui-contract.js +1 -0
- package/dist/gateway/control-ui-csp.js +15 -0
- package/dist/gateway/gateway-config-prompts.shared.js +25 -0
- package/dist/gateway/http-auth-helpers.js +18 -0
- package/dist/gateway/http-common.js +18 -0
- package/dist/gateway/http-endpoint-helpers.js +27 -0
- package/dist/gateway/node-invoke-sanitize.js +11 -0
- package/dist/gateway/node-invoke-system-run-approval.js +205 -0
- package/dist/gateway/probe-auth.js +21 -0
- package/dist/gateway/protocol/index.js +7 -2
- package/dist/gateway/protocol/schema/mesh.js +54 -0
- package/dist/gateway/protocol/schema/protocol-schemas.js +7 -0
- package/dist/gateway/protocol/schema.js +1 -0
- package/dist/gateway/server/ws-connection/auth-messages.js +54 -0
- package/dist/gateway/server-channels.js +11 -0
- package/dist/gateway/server-methods/attachment-normalize.js +16 -0
- package/dist/gateway/server-methods/base-hash.js +8 -0
- package/dist/gateway/server-methods/mesh.js +700 -0
- package/dist/gateway/server-methods/nodes.handlers.invoke-result.js +55 -0
- package/dist/gateway/server-methods/restart-request.js +13 -0
- package/dist/gateway/server-methods/validation.js +8 -0
- package/dist/gateway/server.agent.gateway-server-agent.mocks.js +35 -0
- package/dist/gateway/server.e2e-registry-helpers.js +1 -0
- package/dist/gateway/server.e2e-ws-harness.js +20 -0
- package/dist/gateway/test-helpers.js +2 -0
- package/dist/gateway/test-helpers.server.js +3 -1
- package/dist/gateway/test-http-response.js +12 -0
- package/dist/gateway/test-openai-responses-model.js +20 -0
- package/dist/gateway/test-temp-config.js +30 -0
- package/dist/gateway/test-with-server.js +32 -0
- package/dist/hooks/bundled/bootstrap-extra-files/handler.js +46 -0
- package/dist/imessage/monitor/abort-handler.js +23 -0
- package/dist/imessage/monitor/inbound-processing.js +346 -0
- package/dist/imessage/monitor/parse-notification.js +64 -0
- package/dist/imessage/target-parsing-helpers.js +92 -0
- package/dist/infra/archive.js +244 -20
- package/dist/infra/detect-package-manager.js +26 -0
- package/dist/infra/exec-approvals-allowlist.js +257 -0
- package/dist/infra/exec-approvals-analysis.js +770 -0
- package/dist/infra/exec-approvals.js +13 -0
- package/dist/infra/file-lock.js +1 -0
- package/dist/infra/gemini-auth.js +39 -0
- package/dist/infra/heartbeat-active-hours.js +85 -0
- package/dist/infra/heartbeat-events-filter.js +50 -0
- package/dist/infra/heartbeat-runner.test-utils.js +39 -0
- package/dist/infra/http-body.js +265 -0
- package/dist/infra/install-package-dir.js +50 -0
- package/dist/infra/install-safe-path.js +49 -0
- package/dist/infra/json-files.js +49 -0
- package/dist/infra/jsonl-socket.js +52 -0
- package/dist/infra/map-size.js +14 -0
- package/dist/infra/net/hostname.js +7 -0
- package/dist/infra/npm-registry-spec.js +39 -0
- package/dist/infra/openclaw-root.js +109 -0
- package/dist/infra/outbound/delivery-queue.js +214 -0
- package/dist/infra/outbound/identity.js +23 -0
- package/dist/infra/outbound/message-action-params.js +307 -0
- package/dist/infra/outbound/tool-payload.js +21 -0
- package/dist/infra/package-json.js +23 -0
- package/dist/infra/pairing-files.js +19 -0
- package/dist/infra/pairing-token.js +9 -0
- package/dist/infra/path-prepend.js +51 -0
- package/dist/infra/path-safety.js +16 -0
- package/dist/infra/process-respawn.js +49 -0
- package/dist/infra/runtime-status.js +16 -0
- package/dist/infra/session-cost-usage.types.js +1 -0
- package/dist/infra/session-maintenance-warning.js +89 -0
- package/dist/infra/system-run-command.js +78 -0
- package/dist/infra/tmp-openclaw-dir.js +81 -0
- package/dist/infra/tmp-poolbot-dir.js +2 -0
- package/dist/infra/update-channels.js +19 -0
- package/dist/line/actions.js +45 -0
- package/dist/line/channel-access-token.js +9 -0
- package/dist/line/flex-templates/basic-cards.js +332 -0
- package/dist/line/flex-templates/common.js +18 -0
- package/dist/line/flex-templates/media-control-cards.js +453 -0
- package/dist/line/flex-templates/message.js +10 -0
- package/dist/line/flex-templates/schedule-cards.js +399 -0
- package/dist/line/flex-templates/types.js +1 -0
- package/dist/line/webhook-node.js +100 -0
- package/dist/line/webhook-utils.js +11 -0
- package/dist/logging/diagnostic-session-state.js +73 -0
- package/dist/logging/diagnostic.js +22 -0
- package/dist/logging/timestamps.js +14 -0
- package/dist/markdown/whatsapp.js +62 -0
- package/dist/media/base64.js +34 -0
- package/dist/media/local-roots.js +32 -0
- package/dist/media/outbound-attachment.js +10 -0
- package/dist/media/read-response-with-limit.js +41 -0
- package/dist/media/sniff-mime-from-base64.js +19 -0
- package/dist/media-understanding/audio-preflight.js +67 -0
- package/dist/media-understanding/fs.js +13 -0
- package/dist/media-understanding/output-extract.js +26 -0
- package/dist/media-understanding/providers/audio.test-helpers.js +34 -0
- package/dist/media-understanding/providers/google/inline-data.js +64 -0
- package/dist/media-understanding/providers/shared.js +7 -0
- package/dist/media-understanding/runner.entries.js +459 -0
- package/dist/memory/batch-error-utils.js +11 -0
- package/dist/memory/batch-http.js +27 -0
- package/dist/memory/batch-output.js +29 -0
- package/dist/memory/batch-runner.js +22 -0
- package/dist/memory/batch-upload.js +23 -0
- package/dist/memory/batch-utils.js +26 -0
- package/dist/memory/embeddings-debug.js +11 -0
- package/dist/memory/embeddings-remote-client.js +22 -0
- package/dist/memory/embeddings-remote-fetch.js +14 -0
- package/dist/memory/embeddings.js +36 -9
- package/dist/memory/hybrid.js +24 -5
- package/dist/memory/manager-embedding-ops.js +616 -0
- package/dist/memory/manager-sync-ops.js +953 -0
- package/dist/memory/manager.js +76 -28
- package/dist/memory/mmr.js +164 -0
- package/dist/memory/qmd-manager.js +1061 -0
- package/dist/memory/qmd-query-parser.js +107 -0
- package/dist/memory/qmd-scope.js +93 -0
- package/dist/memory/query-expansion.js +331 -0
- package/dist/memory/search-manager.js +0 -1
- package/dist/memory/sync-index.js +21 -0
- package/dist/memory/sync-progress.js +22 -0
- package/dist/memory/sync-stale.js +30 -0
- package/dist/memory/temporal-decay.js +119 -0
- package/dist/memory/test-embeddings-mock.js +16 -0
- package/dist/memory/test-manager-helpers.js +14 -0
- package/dist/memory/test-runtime-mocks.js +11 -0
- package/dist/node-host/invoke-browser.js +177 -0
- package/dist/node-host/invoke.js +685 -0
- package/dist/pairing/setup-code.js +285 -0
- package/dist/plugin-sdk/account-id.js +1 -0
- package/dist/plugin-sdk/agent-media-payload.js +13 -0
- package/dist/plugin-sdk/allow-from.js +47 -0
- package/dist/plugin-sdk/command-auth.js +23 -0
- package/dist/plugin-sdk/config-paths.js +9 -0
- package/dist/plugin-sdk/file-lock.js +116 -0
- package/dist/plugin-sdk/json-store.js +31 -0
- package/dist/plugin-sdk/onboarding.js +28 -0
- package/dist/plugin-sdk/provider-auth-result.js +29 -0
- package/dist/plugin-sdk/slack-message-actions.js +133 -0
- package/dist/plugin-sdk/status-helpers.js +35 -0
- package/dist/plugin-sdk/text-chunking.js +31 -0
- package/dist/plugin-sdk/tool-send.js +12 -0
- package/dist/plugin-sdk/webhook-path.js +27 -0
- package/dist/plugin-sdk/webhook-targets.js +34 -0
- package/dist/plugins/hooks.test-helpers.js +21 -0
- package/dist/plugins/uninstall.js +171 -0
- package/dist/process/kill-tree.js +98 -0
- package/dist/process/supervisor/adapters/child.js +143 -0
- package/dist/process/supervisor/adapters/env.js +13 -0
- package/dist/process/supervisor/adapters/pty.js +148 -0
- package/dist/process/supervisor/index.js +10 -0
- package/dist/process/supervisor/registry.js +117 -0
- package/dist/process/supervisor/supervisor.js +244 -0
- package/dist/process/supervisor/types.js +1 -0
- package/dist/providers/google-shared.test-helpers.js +75 -0
- package/dist/security/audit-channel.js +419 -0
- package/dist/security/audit-tool-policy.js +1 -0
- package/dist/security/scan-paths.js +12 -0
- package/dist/sessions/input-provenance.js +55 -0
- package/dist/sessions/session-key-utils.js +7 -0
- package/dist/shared/chat-content.js +31 -0
- package/dist/shared/chat-envelope.js +45 -0
- package/dist/shared/config-eval.js +117 -0
- package/dist/shared/device-auth.js +16 -0
- package/dist/shared/entry-metadata.js +9 -0
- package/dist/shared/entry-status.js +25 -0
- package/dist/shared/frontmatter.js +98 -0
- package/dist/shared/model-param-b.js +19 -0
- package/dist/shared/net/ipv4.js +17 -0
- package/dist/shared/node-match.js +53 -0
- package/dist/shared/pid-alive.js +12 -0
- package/dist/shared/process-scoped-map.js +10 -0
- package/dist/shared/requirements.js +128 -0
- package/dist/shared/subagents-format.js +84 -0
- package/dist/shared/usage-aggregates.js +28 -0
- package/dist/signal/monitor/mentions.js +45 -0
- package/dist/signal/rpc-context.js +19 -0
- package/dist/slack/blocks-fallback.js +76 -0
- package/dist/slack/blocks-input.js +40 -0
- package/dist/slack/draft-stream.js +106 -0
- package/dist/slack/message-actions.js +51 -0
- package/dist/slack/modal-metadata.js +32 -0
- package/dist/slack/monitor/events/interactions.js +462 -0
- package/dist/slack/monitor/room-context.js +17 -0
- package/dist/slack/stream-mode.js +41 -0
- package/dist/telegram/bot-native-command-menu.js +64 -0
- package/dist/telegram/bot.media.e2e-harness.js +81 -0
- package/dist/telegram/button-types.js +1 -0
- package/dist/telegram/group-access.js +65 -0
- package/dist/telegram/outbound-params.js +21 -0
- package/dist/telegram/poll-vote-cache.js +21 -0
- package/dist/terminal/health-style.js +36 -0
- package/dist/test-utils/chunk-test-helpers.js +21 -0
- package/dist/test-utils/env.js +72 -0
- package/dist/test-utils/exec-assertions.js +12 -0
- package/dist/test-utils/imessage-test-plugin.js +54 -0
- package/dist/test-utils/mock-http-response.js +17 -0
- package/dist/test-utils/vitest-mock-fn.js +1 -0
- package/dist/tts/tts-core.js +550 -0
- package/dist/utils/chunk-items.js +10 -0
- package/dist/utils/reaction-level.js +52 -0
- package/dist/utils/safe-json.js +22 -0
- package/dist/utils/with-timeout.js +14 -0
- package/dist/web/media.js +17 -5
- package/dist/whatsapp/resolve-outbound-target.js +42 -0
- package/dist/wizard/onboarding.completion.js +74 -0
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/bluebubbles/src/account-resolve.ts +29 -0
- package/extensions/bluebubbles/src/monitor-normalize.ts +796 -0
- package/extensions/bluebubbles/src/monitor-processing.ts +1007 -0
- package/extensions/bluebubbles/src/monitor-reply-cache.ts +185 -0
- package/extensions/bluebubbles/src/monitor-shared.ts +51 -0
- package/extensions/bluebubbles/src/multipart.ts +32 -0
- package/extensions/bluebubbles/src/send-helpers.ts +53 -0
- package/extensions/bluebubbles/src/test-harness.ts +50 -0
- package/extensions/bluebubbles/src/test-mocks.ts +11 -0
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/device-pair/index.ts +554 -0
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/discord/src/channel.js +366 -0
- package/extensions/discord/src/runtime.js +10 -0
- package/extensions/feishu/index.ts +63 -0
- package/extensions/feishu/src/accounts.ts +114 -0
- package/extensions/feishu/src/bitable.ts +739 -0
- package/extensions/feishu/src/bot.ts +965 -0
- package/extensions/feishu/src/channel.ts +351 -0
- package/extensions/feishu/src/client.ts +118 -0
- package/extensions/feishu/src/config-schema.ts +206 -0
- package/extensions/feishu/src/dedup.ts +33 -0
- package/extensions/feishu/src/directory.ts +177 -0
- package/extensions/feishu/src/doc-schema.ts +47 -0
- package/extensions/feishu/src/docx.ts +536 -0
- package/extensions/feishu/src/drive-schema.ts +46 -0
- package/extensions/feishu/src/drive.ts +227 -0
- package/extensions/feishu/src/dynamic-agent.ts +131 -0
- package/extensions/feishu/src/media.ts +449 -0
- package/extensions/feishu/src/mention.ts +126 -0
- package/extensions/feishu/src/monitor.ts +330 -0
- package/extensions/feishu/src/onboarding.ts +359 -0
- package/extensions/feishu/src/outbound.ts +55 -0
- package/extensions/feishu/src/perm-schema.ts +52 -0
- package/extensions/feishu/src/perm.ts +173 -0
- package/extensions/feishu/src/policy.ts +84 -0
- package/extensions/feishu/src/probe.ts +44 -0
- package/extensions/feishu/src/reactions.ts +160 -0
- package/extensions/feishu/src/reply-dispatcher.ts +239 -0
- package/extensions/feishu/src/runtime.ts +14 -0
- package/extensions/feishu/src/send-result.ts +29 -0
- package/extensions/feishu/src/send.ts +335 -0
- package/extensions/feishu/src/streaming-card.ts +223 -0
- package/extensions/feishu/src/targets.ts +78 -0
- package/extensions/feishu/src/tools-config.ts +21 -0
- package/extensions/feishu/src/types.ts +81 -0
- package/extensions/feishu/src/typing.ts +80 -0
- package/extensions/feishu/src/wiki-schema.ts +55 -0
- package/extensions/feishu/src/wiki.ts +232 -0
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/imessage/src/channel.js +253 -0
- package/extensions/imessage/src/runtime.js +10 -0
- package/extensions/irc/index.ts +17 -0
- package/extensions/irc/src/accounts.ts +268 -0
- package/extensions/irc/src/channel.ts +367 -0
- package/extensions/irc/src/client.ts +439 -0
- package/extensions/irc/src/config-schema.ts +97 -0
- package/extensions/irc/src/connect-options.ts +30 -0
- package/extensions/irc/src/control-chars.ts +22 -0
- package/extensions/irc/src/inbound.ts +334 -0
- package/extensions/irc/src/monitor.ts +147 -0
- package/extensions/irc/src/normalize.ts +117 -0
- package/extensions/irc/src/onboarding.ts +479 -0
- package/extensions/irc/src/policy.ts +157 -0
- package/extensions/irc/src/probe.ts +53 -0
- package/extensions/irc/src/protocol.ts +169 -0
- package/extensions/irc/src/runtime.ts +14 -0
- package/extensions/irc/src/send.ts +88 -0
- package/extensions/irc/src/types.ts +93 -0
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +5 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/matrix/src/matrix/client-bootstrap.ts +39 -0
- package/extensions/mattermost/package.json +1 -1
- package/extensions/mattermost/src/mattermost/monitor-onchar.ts +25 -0
- package/extensions/mattermost/src/mattermost/monitor-websocket.ts +221 -0
- package/extensions/mattermost/src/mattermost/reactions.ts +130 -0
- package/extensions/mattermost/src/mattermost/reconnect.ts +103 -0
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/index.ts +161 -0
- package/extensions/minimax-portal-auth/oauth.ts +247 -0
- package/extensions/msteams/CHANGELOG.md +5 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/msteams/src/file-lock.ts +1 -0
- package/extensions/msteams/src/graph.ts +92 -0
- package/extensions/msteams/src/mentions.ts +114 -0
- package/extensions/msteams/src/test-runtime.ts +16 -0
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +5 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/index.ts +177 -0
- package/extensions/phone-control/index.ts +421 -0
- package/extensions/shared/resolve-target-test-helpers.ts +66 -0
- package/extensions/signal/package.json +1 -1
- package/extensions/signal/src/channel.js +273 -0
- package/extensions/signal/src/runtime.js +10 -0
- package/extensions/slack/package.json +1 -1
- package/extensions/slack/src/channel.js +489 -0
- package/extensions/slack/src/runtime.js +10 -0
- package/extensions/talk-voice/index.ts +150 -0
- package/extensions/telegram/package.json +1 -1
- package/extensions/telegram/src/channel.js +424 -0
- package/extensions/telegram/src/runtime.js +10 -0
- package/extensions/thread-ownership/index.ts +133 -0
- package/extensions/tlon/package.json +1 -1
- package/extensions/tlon/src/account-fields.ts +25 -0
- package/extensions/tlon/src/urbit/base-url.ts +57 -0
- package/extensions/tlon/src/urbit/channel-client.ts +157 -0
- package/extensions/tlon/src/urbit/channel-ops.ts +164 -0
- package/extensions/tlon/src/urbit/context.ts +47 -0
- package/extensions/tlon/src/urbit/errors.ts +51 -0
- package/extensions/tlon/src/urbit/fetch.ts +39 -0
- package/extensions/twitch/CHANGELOG.md +5 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/twitch/src/test-fixtures.ts +30 -0
- package/extensions/voice-call/CHANGELOG.md +5 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/voice-call/src/allowlist.ts +19 -0
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/whatsapp/src/channel.js +429 -0
- package/extensions/whatsapp/src/runtime.js +10 -0
- package/extensions/zalo/CHANGELOG.md +5 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +5 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import net from "node:net";
|
|
2
|
+
export async function requestJsonlSocket(params) {
|
|
3
|
+
const { socketPath, payload, timeoutMs, accept } = params;
|
|
4
|
+
return await new Promise((resolve) => {
|
|
5
|
+
const client = new net.Socket();
|
|
6
|
+
let settled = false;
|
|
7
|
+
let buffer = "";
|
|
8
|
+
const finish = (value) => {
|
|
9
|
+
if (settled) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
settled = true;
|
|
13
|
+
try {
|
|
14
|
+
client.destroy();
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// ignore
|
|
18
|
+
}
|
|
19
|
+
resolve(value);
|
|
20
|
+
};
|
|
21
|
+
const timer = setTimeout(() => finish(null), timeoutMs);
|
|
22
|
+
client.on("error", () => finish(null));
|
|
23
|
+
client.connect(socketPath, () => {
|
|
24
|
+
client.write(`${payload}\n`);
|
|
25
|
+
});
|
|
26
|
+
client.on("data", (data) => {
|
|
27
|
+
buffer += data.toString("utf8");
|
|
28
|
+
let idx = buffer.indexOf("\n");
|
|
29
|
+
while (idx !== -1) {
|
|
30
|
+
const line = buffer.slice(0, idx).trim();
|
|
31
|
+
buffer = buffer.slice(idx + 1);
|
|
32
|
+
idx = buffer.indexOf("\n");
|
|
33
|
+
if (!line) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const msg = JSON.parse(line);
|
|
38
|
+
const result = accept(msg);
|
|
39
|
+
if (result === undefined) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
clearTimeout(timer);
|
|
43
|
+
finish(result);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// ignore
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function pruneMapToMaxSize(map, maxSize) {
|
|
2
|
+
const limit = Math.max(0, Math.floor(maxSize));
|
|
3
|
+
if (limit <= 0) {
|
|
4
|
+
map.clear();
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
while (map.size > limit) {
|
|
8
|
+
const oldest = map.keys().next();
|
|
9
|
+
if (oldest.done) {
|
|
10
|
+
break;
|
|
11
|
+
}
|
|
12
|
+
map.delete(oldest.value);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export function validateRegistryNpmSpec(rawSpec) {
|
|
2
|
+
const spec = rawSpec.trim();
|
|
3
|
+
if (!spec) {
|
|
4
|
+
return "missing npm spec";
|
|
5
|
+
}
|
|
6
|
+
if (/\s/.test(spec)) {
|
|
7
|
+
return "unsupported npm spec: whitespace is not allowed";
|
|
8
|
+
}
|
|
9
|
+
// Registry-only: no URLs, git, file, or alias protocols.
|
|
10
|
+
// Keep strict: this runs on the gateway host.
|
|
11
|
+
if (spec.includes("://")) {
|
|
12
|
+
return "unsupported npm spec: URLs are not allowed";
|
|
13
|
+
}
|
|
14
|
+
if (spec.includes("#")) {
|
|
15
|
+
return "unsupported npm spec: git refs are not allowed";
|
|
16
|
+
}
|
|
17
|
+
if (spec.includes(":")) {
|
|
18
|
+
return "unsupported npm spec: protocol specs are not allowed";
|
|
19
|
+
}
|
|
20
|
+
const at = spec.lastIndexOf("@");
|
|
21
|
+
const hasVersion = at > 0;
|
|
22
|
+
const name = hasVersion ? spec.slice(0, at) : spec;
|
|
23
|
+
const version = hasVersion ? spec.slice(at + 1) : "";
|
|
24
|
+
const unscopedName = /^[a-z0-9][a-z0-9-._~]*$/;
|
|
25
|
+
const scopedName = /^@[a-z0-9][a-z0-9-._~]*\/[a-z0-9][a-z0-9-._~]*$/;
|
|
26
|
+
const isValidName = name.startsWith("@") ? scopedName.test(name) : unscopedName.test(name);
|
|
27
|
+
if (!isValidName) {
|
|
28
|
+
return "unsupported npm spec: expected <name> or <name>@<version> from the npm registry";
|
|
29
|
+
}
|
|
30
|
+
if (hasVersion) {
|
|
31
|
+
if (!version) {
|
|
32
|
+
return "unsupported npm spec: missing version/tag after @";
|
|
33
|
+
}
|
|
34
|
+
if (/[\\/]/.test(version)) {
|
|
35
|
+
return "unsupported npm spec: invalid version/tag";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import fsSync from "node:fs";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
const CORE_PACKAGE_NAMES = new Set(["poolbot"]);
|
|
6
|
+
async function readPackageName(dir) {
|
|
7
|
+
try {
|
|
8
|
+
const raw = await fs.readFile(path.join(dir, "package.json"), "utf-8");
|
|
9
|
+
const parsed = JSON.parse(raw);
|
|
10
|
+
return typeof parsed.name === "string" ? parsed.name : null;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function readPackageNameSync(dir) {
|
|
17
|
+
try {
|
|
18
|
+
const raw = fsSync.readFileSync(path.join(dir, "package.json"), "utf-8");
|
|
19
|
+
const parsed = JSON.parse(raw);
|
|
20
|
+
return typeof parsed.name === "string" ? parsed.name : null;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function findPackageRoot(startDir, maxDepth = 12) {
|
|
27
|
+
let current = path.resolve(startDir);
|
|
28
|
+
for (let i = 0; i < maxDepth; i += 1) {
|
|
29
|
+
const name = await readPackageName(current);
|
|
30
|
+
if (name && CORE_PACKAGE_NAMES.has(name)) {
|
|
31
|
+
return current;
|
|
32
|
+
}
|
|
33
|
+
const parent = path.dirname(current);
|
|
34
|
+
if (parent === current) {
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
current = parent;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
function findPackageRootSync(startDir, maxDepth = 12) {
|
|
42
|
+
let current = path.resolve(startDir);
|
|
43
|
+
for (let i = 0; i < maxDepth; i += 1) {
|
|
44
|
+
const name = readPackageNameSync(current);
|
|
45
|
+
if (name && CORE_PACKAGE_NAMES.has(name)) {
|
|
46
|
+
return current;
|
|
47
|
+
}
|
|
48
|
+
const parent = path.dirname(current);
|
|
49
|
+
if (parent === current) {
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
current = parent;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
function candidateDirsFromArgv1(argv1) {
|
|
57
|
+
const normalized = path.resolve(argv1);
|
|
58
|
+
const candidates = [path.dirname(normalized)];
|
|
59
|
+
// Resolve symlinks for version managers (nvm, fnm, n, Homebrew/Linuxbrew)
|
|
60
|
+
// that create symlinks in bin/ pointing to the real package location.
|
|
61
|
+
try {
|
|
62
|
+
const resolved = fsSync.realpathSync(normalized);
|
|
63
|
+
if (resolved !== normalized) {
|
|
64
|
+
candidates.push(path.dirname(resolved));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// realpathSync throws if path doesn't exist; keep original candidates
|
|
69
|
+
}
|
|
70
|
+
const parts = normalized.split(path.sep);
|
|
71
|
+
const binIndex = parts.lastIndexOf(".bin");
|
|
72
|
+
if (binIndex > 0 && parts[binIndex - 1] === "node_modules") {
|
|
73
|
+
const binName = path.basename(normalized);
|
|
74
|
+
const nodeModulesDir = parts.slice(0, binIndex).join(path.sep);
|
|
75
|
+
candidates.push(path.join(nodeModulesDir, binName));
|
|
76
|
+
}
|
|
77
|
+
return candidates;
|
|
78
|
+
}
|
|
79
|
+
export async function resolveOpenClawPackageRoot(opts) {
|
|
80
|
+
for (const candidate of buildCandidates(opts)) {
|
|
81
|
+
const found = await findPackageRoot(candidate);
|
|
82
|
+
if (found) {
|
|
83
|
+
return found;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
export function resolveOpenClawPackageRootSync(opts) {
|
|
89
|
+
for (const candidate of buildCandidates(opts)) {
|
|
90
|
+
const found = findPackageRootSync(candidate);
|
|
91
|
+
if (found) {
|
|
92
|
+
return found;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
function buildCandidates(opts) {
|
|
98
|
+
const candidates = [];
|
|
99
|
+
if (opts.moduleUrl) {
|
|
100
|
+
candidates.push(path.dirname(fileURLToPath(opts.moduleUrl)));
|
|
101
|
+
}
|
|
102
|
+
if (opts.argv1) {
|
|
103
|
+
candidates.push(...candidateDirsFromArgv1(opts.argv1));
|
|
104
|
+
}
|
|
105
|
+
if (opts.cwd) {
|
|
106
|
+
candidates.push(opts.cwd);
|
|
107
|
+
}
|
|
108
|
+
return candidates;
|
|
109
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { resolveStateDir } from "../../config/paths.js";
|
|
5
|
+
const QUEUE_DIRNAME = "delivery-queue";
|
|
6
|
+
const FAILED_DIRNAME = "failed";
|
|
7
|
+
const MAX_RETRIES = 5;
|
|
8
|
+
/** Backoff delays in milliseconds indexed by retry count (1-based). */
|
|
9
|
+
const BACKOFF_MS = [
|
|
10
|
+
5_000, // retry 1: 5s
|
|
11
|
+
25_000, // retry 2: 25s
|
|
12
|
+
120_000, // retry 3: 2m
|
|
13
|
+
600_000, // retry 4: 10m
|
|
14
|
+
];
|
|
15
|
+
function resolveQueueDir(stateDir) {
|
|
16
|
+
const base = stateDir ?? resolveStateDir();
|
|
17
|
+
return path.join(base, QUEUE_DIRNAME);
|
|
18
|
+
}
|
|
19
|
+
function resolveFailedDir(stateDir) {
|
|
20
|
+
return path.join(resolveQueueDir(stateDir), FAILED_DIRNAME);
|
|
21
|
+
}
|
|
22
|
+
/** Ensure the queue directory (and failed/ subdirectory) exist. */
|
|
23
|
+
export async function ensureQueueDir(stateDir) {
|
|
24
|
+
const queueDir = resolveQueueDir(stateDir);
|
|
25
|
+
await fs.promises.mkdir(queueDir, { recursive: true, mode: 0o700 });
|
|
26
|
+
await fs.promises.mkdir(resolveFailedDir(stateDir), { recursive: true, mode: 0o700 });
|
|
27
|
+
return queueDir;
|
|
28
|
+
}
|
|
29
|
+
export async function enqueueDelivery(params, stateDir) {
|
|
30
|
+
const queueDir = await ensureQueueDir(stateDir);
|
|
31
|
+
const id = crypto.randomUUID();
|
|
32
|
+
const entry = {
|
|
33
|
+
id,
|
|
34
|
+
enqueuedAt: Date.now(),
|
|
35
|
+
channel: params.channel,
|
|
36
|
+
to: params.to,
|
|
37
|
+
accountId: params.accountId,
|
|
38
|
+
payloads: params.payloads,
|
|
39
|
+
threadId: params.threadId,
|
|
40
|
+
replyToId: params.replyToId,
|
|
41
|
+
bestEffort: params.bestEffort,
|
|
42
|
+
gifPlayback: params.gifPlayback,
|
|
43
|
+
silent: params.silent,
|
|
44
|
+
mirror: params.mirror,
|
|
45
|
+
retryCount: 0,
|
|
46
|
+
};
|
|
47
|
+
const filePath = path.join(queueDir, `${id}.json`);
|
|
48
|
+
const tmp = `${filePath}.${process.pid}.tmp`;
|
|
49
|
+
const json = JSON.stringify(entry, null, 2);
|
|
50
|
+
await fs.promises.writeFile(tmp, json, { encoding: "utf-8", mode: 0o600 });
|
|
51
|
+
await fs.promises.rename(tmp, filePath);
|
|
52
|
+
return id;
|
|
53
|
+
}
|
|
54
|
+
/** Remove a successfully delivered entry from the queue. */
|
|
55
|
+
export async function ackDelivery(id, stateDir) {
|
|
56
|
+
const filePath = path.join(resolveQueueDir(stateDir), `${id}.json`);
|
|
57
|
+
try {
|
|
58
|
+
await fs.promises.unlink(filePath);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const code = err && typeof err === "object" && "code" in err
|
|
62
|
+
? String(err.code)
|
|
63
|
+
: null;
|
|
64
|
+
if (code !== "ENOENT") {
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
// Already removed — no-op.
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Update a queue entry after a failed delivery attempt. */
|
|
71
|
+
export async function failDelivery(id, error, stateDir) {
|
|
72
|
+
const filePath = path.join(resolveQueueDir(stateDir), `${id}.json`);
|
|
73
|
+
const raw = await fs.promises.readFile(filePath, "utf-8");
|
|
74
|
+
const entry = JSON.parse(raw);
|
|
75
|
+
entry.retryCount += 1;
|
|
76
|
+
entry.lastError = error;
|
|
77
|
+
const tmp = `${filePath}.${process.pid}.tmp`;
|
|
78
|
+
await fs.promises.writeFile(tmp, JSON.stringify(entry, null, 2), {
|
|
79
|
+
encoding: "utf-8",
|
|
80
|
+
mode: 0o600,
|
|
81
|
+
});
|
|
82
|
+
await fs.promises.rename(tmp, filePath);
|
|
83
|
+
}
|
|
84
|
+
/** Load all pending delivery entries from the queue directory. */
|
|
85
|
+
export async function loadPendingDeliveries(stateDir) {
|
|
86
|
+
const queueDir = resolveQueueDir(stateDir);
|
|
87
|
+
let files;
|
|
88
|
+
try {
|
|
89
|
+
files = await fs.promises.readdir(queueDir);
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
const code = err && typeof err === "object" && "code" in err
|
|
93
|
+
? String(err.code)
|
|
94
|
+
: null;
|
|
95
|
+
if (code === "ENOENT") {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
throw err;
|
|
99
|
+
}
|
|
100
|
+
const entries = [];
|
|
101
|
+
for (const file of files) {
|
|
102
|
+
if (!file.endsWith(".json")) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const filePath = path.join(queueDir, file);
|
|
106
|
+
try {
|
|
107
|
+
const stat = await fs.promises.stat(filePath);
|
|
108
|
+
if (!stat.isFile()) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const raw = await fs.promises.readFile(filePath, "utf-8");
|
|
112
|
+
entries.push(JSON.parse(raw));
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Skip malformed or inaccessible entries.
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return entries;
|
|
119
|
+
}
|
|
120
|
+
/** Move a queue entry to the failed/ subdirectory. */
|
|
121
|
+
export async function moveToFailed(id, stateDir) {
|
|
122
|
+
const queueDir = resolveQueueDir(stateDir);
|
|
123
|
+
const failedDir = resolveFailedDir(stateDir);
|
|
124
|
+
await fs.promises.mkdir(failedDir, { recursive: true, mode: 0o700 });
|
|
125
|
+
const src = path.join(queueDir, `${id}.json`);
|
|
126
|
+
const dest = path.join(failedDir, `${id}.json`);
|
|
127
|
+
await fs.promises.rename(src, dest);
|
|
128
|
+
}
|
|
129
|
+
/** Compute the backoff delay in ms for a given retry count. */
|
|
130
|
+
export function computeBackoffMs(retryCount) {
|
|
131
|
+
if (retryCount <= 0) {
|
|
132
|
+
return 0;
|
|
133
|
+
}
|
|
134
|
+
return BACKOFF_MS[Math.min(retryCount - 1, BACKOFF_MS.length - 1)] ?? BACKOFF_MS.at(-1) ?? 0;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* On gateway startup, scan the delivery queue and retry any pending entries.
|
|
138
|
+
* Uses exponential backoff and moves entries that exceed MAX_RETRIES to failed/.
|
|
139
|
+
*/
|
|
140
|
+
export async function recoverPendingDeliveries(opts) {
|
|
141
|
+
const pending = await loadPendingDeliveries(opts.stateDir);
|
|
142
|
+
if (pending.length === 0) {
|
|
143
|
+
return { recovered: 0, failed: 0, skipped: 0 };
|
|
144
|
+
}
|
|
145
|
+
// Process oldest first.
|
|
146
|
+
pending.sort((a, b) => a.enqueuedAt - b.enqueuedAt);
|
|
147
|
+
opts.log.info(`Found ${pending.length} pending delivery entries — starting recovery`);
|
|
148
|
+
const delayFn = opts.delay ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
149
|
+
const deadline = Date.now() + (opts.maxRecoveryMs ?? 60_000);
|
|
150
|
+
let recovered = 0;
|
|
151
|
+
let failed = 0;
|
|
152
|
+
let skipped = 0;
|
|
153
|
+
for (const entry of pending) {
|
|
154
|
+
const now = Date.now();
|
|
155
|
+
if (now >= deadline) {
|
|
156
|
+
const deferred = pending.length - recovered - failed - skipped;
|
|
157
|
+
opts.log.warn(`Recovery time budget exceeded — ${deferred} entries deferred to next restart`);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
if (entry.retryCount >= MAX_RETRIES) {
|
|
161
|
+
opts.log.warn(`Delivery ${entry.id} exceeded max retries (${entry.retryCount}/${MAX_RETRIES}) — moving to failed/`);
|
|
162
|
+
try {
|
|
163
|
+
await moveToFailed(entry.id, opts.stateDir);
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
opts.log.error(`Failed to move entry ${entry.id} to failed/: ${String(err)}`);
|
|
167
|
+
}
|
|
168
|
+
skipped += 1;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const backoff = computeBackoffMs(entry.retryCount + 1);
|
|
172
|
+
if (backoff > 0) {
|
|
173
|
+
if (now + backoff >= deadline) {
|
|
174
|
+
const deferred = pending.length - recovered - failed - skipped;
|
|
175
|
+
opts.log.warn(`Recovery time budget exceeded — ${deferred} entries deferred to next restart`);
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
opts.log.info(`Waiting ${backoff}ms before retrying delivery ${entry.id}`);
|
|
179
|
+
await delayFn(backoff);
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
await opts.deliver({
|
|
183
|
+
cfg: opts.cfg,
|
|
184
|
+
channel: entry.channel,
|
|
185
|
+
to: entry.to,
|
|
186
|
+
accountId: entry.accountId,
|
|
187
|
+
payloads: entry.payloads,
|
|
188
|
+
threadId: entry.threadId,
|
|
189
|
+
replyToId: entry.replyToId,
|
|
190
|
+
bestEffort: entry.bestEffort,
|
|
191
|
+
gifPlayback: entry.gifPlayback,
|
|
192
|
+
silent: entry.silent,
|
|
193
|
+
mirror: entry.mirror,
|
|
194
|
+
skipQueue: true, // Prevent re-enqueueing during recovery
|
|
195
|
+
});
|
|
196
|
+
await ackDelivery(entry.id, opts.stateDir);
|
|
197
|
+
recovered += 1;
|
|
198
|
+
opts.log.info(`Recovered delivery ${entry.id} to ${entry.channel}:${entry.to}`);
|
|
199
|
+
}
|
|
200
|
+
catch (err) {
|
|
201
|
+
try {
|
|
202
|
+
await failDelivery(entry.id, err instanceof Error ? err.message : String(err), opts.stateDir);
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// Best-effort update.
|
|
206
|
+
}
|
|
207
|
+
failed += 1;
|
|
208
|
+
opts.log.warn(`Retry failed for delivery ${entry.id}: ${err instanceof Error ? err.message : String(err)}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
opts.log.info(`Delivery recovery complete: ${recovered} recovered, ${failed} failed, ${skipped} skipped (max retries)`);
|
|
212
|
+
return { recovered, failed, skipped };
|
|
213
|
+
}
|
|
214
|
+
export { MAX_RETRIES };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { resolveAgentAvatar } from "../../agents/identity-avatar.js";
|
|
2
|
+
import { resolveAgentIdentity } from "../../agents/identity.js";
|
|
3
|
+
export function normalizeOutboundIdentity(identity) {
|
|
4
|
+
if (!identity) {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
const name = identity.name?.trim() || undefined;
|
|
8
|
+
const avatarUrl = identity.avatarUrl?.trim() || undefined;
|
|
9
|
+
const emoji = identity.emoji?.trim() || undefined;
|
|
10
|
+
if (!name && !avatarUrl && !emoji) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
return { name, avatarUrl, emoji };
|
|
14
|
+
}
|
|
15
|
+
export function resolveAgentOutboundIdentity(cfg, agentId) {
|
|
16
|
+
const agentIdentity = resolveAgentIdentity(cfg, agentId);
|
|
17
|
+
const avatar = resolveAgentAvatar(cfg, agentId);
|
|
18
|
+
return normalizeOutboundIdentity({
|
|
19
|
+
name: agentIdentity?.name,
|
|
20
|
+
emoji: agentIdentity?.emoji,
|
|
21
|
+
avatarUrl: avatar.kind === "remote" ? avatar.url : undefined,
|
|
22
|
+
});
|
|
23
|
+
}
|