@poolzin/pool-bot 2026.2.21 → 2026.2.23
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 +25 -0
- package/dist/agents/api-key-rotation.js +47 -0
- package/dist/agents/apply-patch-update.js +19 -9
- package/dist/agents/apply-patch.js +72 -47
- package/dist/agents/bash-tools.exec.js +141 -559
- package/dist/agents/cli-backends.js +49 -6
- package/dist/agents/cli-runner/helpers.js +69 -152
- package/dist/agents/cli-runner.js +70 -19
- package/dist/agents/identity.js +20 -1
- package/dist/agents/image-sanitization.js +9 -0
- package/dist/agents/live-auth-keys.js +123 -26
- package/dist/agents/live-model-filter.js +13 -4
- package/dist/agents/model-catalog.js +40 -9
- package/dist/agents/model-forward-compat.js +60 -23
- package/dist/agents/model-selection.js +134 -41
- package/dist/agents/pi-auth-json.js +2 -2
- package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
- package/dist/agents/pi-embedded-helpers/errors.js +140 -15
- package/dist/agents/pi-embedded-helpers/images.js +22 -12
- package/dist/agents/pi-embedded-helpers.js +2 -2
- package/dist/agents/pi-embedded-runner/abort.js +10 -3
- package/dist/agents/pi-embedded-runner/compact.js +230 -32
- package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
- package/dist/agents/pi-embedded-runner/google.js +109 -19
- package/dist/agents/pi-embedded-runner/history.js +35 -17
- package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
- package/dist/agents/pi-embedded-runner/run/images.js +81 -55
- package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
- package/dist/agents/pi-embedded-runner/run.js +193 -25
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
- package/dist/agents/pi-embedded-runner/runs.js +17 -8
- package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
- package/dist/agents/pi-embedded-runner.js +1 -1
- package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
- package/dist/agents/pi-embedded-subscribe.js +37 -0
- package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
- package/dist/agents/pi-model-discovery.js +9 -2
- package/dist/agents/pi-tool-definition-adapter.js +60 -8
- package/dist/agents/pi-tools.before-tool-call.js +1 -1
- package/dist/agents/pi-tools.js +113 -94
- package/dist/agents/pi-tools.read.js +337 -38
- package/dist/agents/poolbot-tools.js +14 -5
- package/dist/agents/sandbox/docker.js +10 -5
- package/dist/agents/sandbox/registry.js +96 -46
- package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
- package/dist/agents/sandbox-paths.js +43 -10
- package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
- package/dist/agents/session-tool-result-guard.js +39 -39
- package/dist/agents/session-transcript-repair.js +36 -33
- package/dist/agents/session-write-lock.js +62 -44
- package/dist/agents/skills/frontmatter.js +49 -88
- package/dist/agents/skills/workspace.js +335 -28
- package/dist/agents/subagent-announce.js +508 -174
- package/dist/agents/subagent-registry.js +45 -4
- package/dist/agents/subagent-spawn.js +16 -33
- package/dist/agents/system-prompt-report.js +27 -10
- package/dist/agents/system-prompt.js +26 -32
- package/dist/agents/tool-call-id.js +69 -17
- package/dist/agents/tool-display-common.js +1 -1
- package/dist/agents/tool-images.js +64 -31
- package/dist/agents/tools/canvas-tool.js +17 -11
- package/dist/agents/tools/common.js +37 -19
- package/dist/agents/tools/cron-tool.js +40 -38
- package/dist/agents/tools/gateway.js +70 -2
- package/dist/agents/tools/message-tool.js +181 -40
- package/dist/agents/tools/nodes-tool.js +128 -36
- package/dist/agents/tools/nodes-utils.js +12 -38
- package/dist/agents/tools/session-status-tool.js +24 -71
- package/dist/agents/tools/sessions-helpers.js +38 -210
- package/dist/agents/tools/sessions-spawn-tool.js +28 -198
- package/dist/agents/tools/telegram-actions.js +58 -7
- package/dist/agents/tools/web-fetch-utils.js +112 -7
- package/dist/agents/tools/web-fetch.js +279 -175
- package/dist/agents/tools/web-shared.js +71 -8
- package/dist/agents/usage.js +25 -16
- package/dist/auto-reply/commands-registry.data.js +85 -11
- package/dist/auto-reply/dispatch.js +40 -21
- package/dist/auto-reply/reply/abort.js +102 -33
- package/dist/auto-reply/reply/commands-core.js +82 -33
- package/dist/auto-reply/reply/commands-export-session.js +1 -1
- package/dist/auto-reply/reply/commands-info.js +41 -12
- package/dist/auto-reply/reply/commands-subagents.js +352 -100
- package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
- package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
- package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
- package/dist/auto-reply/reply/inbound-meta.js +12 -1
- package/dist/auto-reply/reply/mentions.js +18 -11
- package/dist/auto-reply/reply/normalize-reply.js +17 -8
- package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
- package/dist/auto-reply/reply/session.js +102 -21
- package/dist/auto-reply/reply/streaming-directives.js +16 -5
- package/dist/auto-reply/status.js +73 -50
- package/dist/browser/extension-relay.js +3 -3
- package/dist/browser/http-auth.js +1 -1
- package/dist/browser/paths.js +2 -2
- package/dist/build-info.json +3 -3
- package/dist/channels/allowlist-match.js +20 -0
- package/dist/channels/allowlists/resolve-utils.js +65 -2
- package/dist/channels/chat-type.js +8 -4
- package/dist/channels/dock.js +127 -35
- package/dist/channels/draft-stream-loop.js +6 -2
- package/dist/channels/plugins/actions/telegram.js +42 -18
- package/dist/channels/plugins/allowlist-match.js +1 -1
- package/dist/channels/plugins/group-mentions.js +51 -41
- package/dist/channels/plugins/message-action-names.js +2 -0
- package/dist/channels/plugins/message-actions.js +24 -5
- package/dist/channels/plugins/normalize/discord.js +26 -4
- package/dist/channels/plugins/normalize/signal.js +35 -22
- package/dist/channels/plugins/onboarding/helpers.js +8 -26
- package/dist/channels/plugins/outbound/imessage.js +15 -14
- package/dist/channels/registry.js +20 -7
- package/dist/cli/acp-cli.js +7 -5
- package/dist/cli/browser-cli-extension.js +25 -12
- package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
- package/dist/cli/browser-cli-state.js +101 -145
- package/dist/cli/command-options.js +28 -0
- package/dist/cli/completion-cli.js +6 -6
- package/dist/cli/cron-cli/register.cron-add.js +25 -1
- package/dist/cli/cron-cli/register.cron-edit.js +44 -0
- package/dist/cli/cron-cli/shared.js +7 -1
- package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
- package/dist/cli/daemon-cli/lifecycle.js +23 -247
- package/dist/cli/daemon-cli/register-service-commands.js +25 -4
- package/dist/cli/daemon-cli.js +1 -0
- package/dist/cli/devices-cli.js +33 -20
- package/dist/cli/gateway-cli/register.js +37 -105
- package/dist/cli/gateway-cli/run.js +49 -11
- package/dist/cli/nodes-camera.js +59 -4
- package/dist/cli/nodes-cli/register.camera.js +27 -24
- package/dist/cli/nodes-cli/rpc.js +21 -38
- package/dist/cli/qr-cli.js +2 -2
- package/dist/cli/skills-cli.format.js +2 -2
- package/dist/cli/update-cli/progress.js +2 -2
- package/dist/cli/update-cli/restart-helper.js +28 -7
- package/dist/cli/update-cli/shared.js +7 -7
- package/dist/cli/update-cli/status.js +1 -1
- package/dist/cli/update-cli/update-command.js +14 -8
- package/dist/cli/update-cli/wizard.js +2 -2
- package/dist/cli/update-cli.js +21 -1027
- package/dist/commands/auth-choice.apply.anthropic.js +10 -2
- package/dist/commands/channels/add-mutators.js +3 -35
- package/dist/commands/channels/add.js +39 -51
- package/dist/commands/config-validation.js +1 -1
- package/dist/commands/configure.gateway-auth.js +52 -15
- package/dist/commands/configure.gateway.js +84 -40
- package/dist/commands/doctor-completion.js +3 -3
- package/dist/commands/doctor-config-flow.js +536 -16
- package/dist/commands/doctor-gateway-services.js +103 -79
- package/dist/commands/doctor-memory-search.js +9 -9
- package/dist/commands/doctor-platform-notes.js +57 -30
- package/dist/commands/doctor-prompter.js +26 -15
- package/dist/commands/doctor-session-locks.js +1 -1
- package/dist/commands/doctor.js +21 -9
- package/dist/commands/model-picker.js +120 -95
- package/dist/commands/models/set.js +2 -21
- package/dist/commands/models/shared.js +65 -37
- package/dist/commands/onboard-helpers.js +81 -39
- package/dist/commands/openai-codex-oauth.js +1 -1
- package/dist/commands/sessions.js +52 -53
- package/dist/commands/status.summary.js +52 -34
- package/dist/commands/test-wizard-helpers.js +2 -2
- package/dist/config/defaults.js +79 -42
- package/dist/config/group-policy.js +50 -18
- package/dist/config/includes.js +37 -10
- package/dist/config/schema.help.js +5 -4
- package/dist/config/schema.hints.js +2 -2
- package/dist/config/schema.labels.js +1 -0
- package/dist/config/sessions/group.js +12 -11
- package/dist/config/sessions/paths.js +137 -11
- package/dist/config/sessions/store.js +185 -65
- package/dist/config/sessions/types.js +15 -1
- package/dist/config/sessions.js +1 -0
- package/dist/config/telegram-custom-commands.js +3 -2
- package/dist/config/types.js +2 -0
- package/dist/config/zod-schema.agent-defaults.js +6 -27
- package/dist/config/zod-schema.agent-runtime.js +171 -79
- package/dist/config/zod-schema.providers-core.js +138 -65
- package/dist/config/zod-schema.session.js +49 -22
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
- package/dist/cron/isolated-agent/run.js +224 -57
- package/dist/cron/normalize.js +48 -45
- package/dist/cron/run-log.js +14 -0
- package/dist/cron/service/jobs.js +190 -28
- package/dist/cron/service/normalize.js +29 -11
- package/dist/cron/service/store.js +30 -44
- package/dist/cron/service/timer.js +182 -96
- package/dist/cron/service.js +3 -0
- package/dist/cron/stagger.js +37 -0
- package/dist/daemon/inspect.js +132 -92
- package/dist/daemon/runtime-paths.js +25 -4
- package/dist/daemon/service-audit.js +47 -16
- package/dist/discord/accounts.js +23 -20
- package/dist/discord/monitor/agent-components.js +1115 -219
- package/dist/discord/monitor/allow-list.js +114 -34
- package/dist/discord/monitor/listeners.js +204 -97
- package/dist/discord/monitor/message-handler.js +21 -10
- package/dist/discord/monitor/message-handler.preflight.js +195 -101
- package/dist/discord/monitor/message-handler.process.js +384 -123
- package/dist/discord/monitor/message-utils.js +86 -23
- package/dist/discord/monitor/native-command.js +77 -57
- package/dist/discord/monitor/provider.js +122 -117
- package/dist/discord/monitor/reply-context.js +20 -16
- package/dist/discord/monitor/reply-delivery.js +40 -8
- package/dist/discord/monitor/rest-fetch.js +22 -0
- package/dist/discord/monitor/threading.js +117 -24
- package/dist/discord/send.js +2 -1
- package/dist/discord/send.outbound.js +124 -11
- package/dist/discord/send.shared.js +112 -72
- package/dist/discord/voice-message.js +3 -3
- package/dist/gateway/auth.js +119 -44
- package/dist/gateway/call.js +76 -34
- package/dist/gateway/channel-health-monitor.js +57 -50
- package/dist/gateway/client.js +63 -29
- package/dist/gateway/control-ui-contract.js +1 -1
- package/dist/gateway/gateway-config-prompts.shared.js +2 -2
- package/dist/gateway/net.js +109 -1
- package/dist/gateway/protocol/index.js +5 -8
- package/dist/gateway/protocol/schema/agent.js +19 -1
- package/dist/gateway/protocol/schema/channels.js +21 -0
- package/dist/gateway/protocol/schema/cron.js +43 -30
- package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
- package/dist/gateway/protocol/schema/sessions.js +5 -1
- package/dist/gateway/protocol/schema.js +0 -1
- package/dist/gateway/server/presence-events.js +12 -0
- package/dist/gateway/server/ws-connection/message-handler.js +203 -212
- package/dist/gateway/server/ws-connection.js +58 -21
- package/dist/gateway/server-broadcast.js +18 -13
- package/dist/gateway/server-cron.js +177 -10
- package/dist/gateway/server-methods/agent-job.js +131 -38
- package/dist/gateway/server-methods/send.js +60 -14
- package/dist/gateway/server-methods/sessions.js +160 -96
- package/dist/gateway/server-methods/system.js +5 -7
- package/dist/gateway/server-methods-list.js +8 -0
- package/dist/gateway/server-methods.js +24 -8
- package/dist/gateway/server-node-events.js +278 -68
- package/dist/gateway/session-utils.fs.js +316 -75
- package/dist/gateway/session-utils.js +224 -70
- package/dist/gateway/sessions-patch.js +63 -20
- package/dist/gateway/test-temp-config.js +1 -1
- package/dist/gateway/tools-invoke-http.js +118 -70
- package/dist/gateway/ws-log.js +135 -107
- package/dist/hooks/frontmatter.js +36 -82
- package/dist/hooks/install.js +149 -139
- package/dist/hooks/internal-hooks.js +29 -4
- package/dist/hooks/plugin-hooks.js +2 -1
- package/dist/imessage/monitor/deliver.js +10 -4
- package/dist/imessage/monitor/monitor-provider.js +138 -375
- package/dist/imessage/monitor/runtime.js +4 -8
- package/dist/imessage/send.js +65 -19
- package/dist/infra/exec-approvals-allowlist.js +7 -0
- package/dist/infra/exec-approvals.js +35 -920
- package/dist/infra/exec-safe-bin-trust.js +64 -0
- package/dist/infra/heartbeat-runner.js +207 -134
- package/dist/infra/heartbeat-wake.js +183 -22
- package/dist/infra/install-source-utils.js +47 -0
- package/dist/infra/net/ssrf.js +170 -36
- package/dist/infra/outbound/deliver.js +224 -58
- package/dist/infra/outbound/message-action-spec.js +12 -5
- package/dist/infra/outbound/outbound-session.js +27 -25
- package/dist/infra/poolbot-root.js +32 -22
- package/dist/infra/ports.js +14 -11
- package/dist/infra/skills-remote.js +48 -37
- package/dist/infra/system-events.js +25 -11
- package/dist/infra/system-presence.js +26 -33
- package/dist/infra/tmp-poolbot-dir.js +81 -2
- package/dist/infra/wsl.js +37 -1
- package/dist/line/bot-message-context.js +163 -191
- package/dist/logging/subsystem.js +59 -22
- package/dist/markdown/ir.js +124 -50
- package/dist/media/store.js +1 -1
- package/dist/media-understanding/runner.entries.js +42 -25
- package/dist/media-understanding/runner.js +53 -488
- package/dist/memory/embeddings-gemini.js +53 -38
- package/dist/memory/manager-embedding-ops.js +48 -69
- package/dist/pairing/pairing-store.js +178 -119
- package/dist/plugin-sdk/index.js +34 -6
- package/dist/plugins/hooks.js +135 -14
- package/dist/plugins/install.js +190 -152
- package/dist/polls.js +11 -0
- package/dist/routing/resolve-route.js +190 -56
- package/dist/routing/session-key.js +38 -22
- package/dist/runtime.js +35 -9
- package/dist/security/audit-channel.js +1 -1
- package/dist/sessions/session-key-utils.js +29 -11
- package/dist/shared/frontmatter.js +5 -5
- package/dist/shared/node-list-types.js +1 -0
- package/dist/shared/string-normalization.js +15 -0
- package/dist/signal/monitor/event-handler.js +68 -36
- package/dist/signal/send.js +29 -37
- package/dist/slack/monitor/allow-list.js +10 -11
- package/dist/slack/monitor/commands.js +14 -3
- package/dist/slack/monitor/events/interactions.js +4 -4
- package/dist/slack/monitor/media.js +224 -16
- package/dist/slack/monitor/message-handler/dispatch.js +247 -13
- package/dist/slack/monitor/message-handler/prepare.js +128 -45
- package/dist/slack/monitor/slash.js +357 -144
- package/dist/slack/streaming.js +77 -0
- package/dist/telegram/accounts.js +40 -13
- package/dist/telegram/allowed-updates.js +3 -0
- package/dist/telegram/bot/delivery.js +129 -66
- package/dist/telegram/bot/helpers.js +136 -122
- package/dist/telegram/bot-handlers.js +600 -339
- package/dist/telegram/bot-message-context.js +115 -73
- package/dist/telegram/bot-message-dispatch.js +235 -104
- package/dist/telegram/bot-native-command-menu.js +3 -1
- package/dist/telegram/bot-native-commands.js +213 -193
- package/dist/telegram/bot.js +24 -132
- package/dist/telegram/draft-stream.js +84 -75
- package/dist/telegram/format.js +150 -6
- package/dist/telegram/send.js +415 -255
- package/dist/telegram/targets.js +21 -2
- package/dist/telegram/update-offset-store.js +19 -3
- package/dist/terminal/restore.js +5 -2
- package/dist/test-utils/fetch-mock.js +5 -0
- package/dist/version.js +18 -5
- package/dist/web/auto-reply/monitor/broadcast.js +7 -3
- package/dist/web/auto-reply/monitor/on-message.js +6 -3
- package/dist/web/inbound/media.js +34 -8
- package/dist/web/inbound/monitor.js +34 -17
- package/dist/web/inbound/send-api.js +18 -17
- package/dist/web/outbound.js +12 -5
- package/dist/wizard/clack-prompter.js +40 -7
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/device-pair/index.ts +2 -2
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- 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/irc/package.json +1 -1
- package/extensions/irc/src/accounts.ts +1 -1
- package/extensions/irc/src/onboarding.ts +4 -4
- 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 +10 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +10 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +10 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +10 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +10 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +10 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +10 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
- package/skills/apple-reminders/SKILL.md +100 -49
- package/skills/coding-agent/SKILL.md +34 -28
- package/skills/github/SKILL.md +131 -16
- package/skills/imsg/SKILL.md +112 -15
- package/skills/openhue/SKILL.md +101 -19
- package/skills/tmux/SKILL.md +111 -79
- package/skills/weather/SKILL.md +88 -25
- package/dist/agents/openclaw-tools.js +0 -151
- package/dist/agents/tool-security.js +0 -96
- package/dist/gateway/url-validation.js +0 -94
- package/dist/infra/openclaw-root.js +0 -109
- package/dist/infra/tmp-openclaw-dir.js +0 -81
- package/dist/media/path-sanitization.js +0 -78
|
@@ -2,33 +2,20 @@ import { chunkByParagraph, chunkMarkdownTextWithMode, resolveChunkMode, resolveT
|
|
|
2
2
|
import { resolveChannelMediaMaxBytes } from "../../channels/plugins/media-limits.js";
|
|
3
3
|
import { loadChannelOutboundAdapter } from "../../channels/plugins/outbound/load.js";
|
|
4
4
|
import { resolveMarkdownTableMode } from "../../config/markdown-tables.js";
|
|
5
|
+
import { appendAssistantMessageToSessionTranscript, resolveMirroredTranscriptText, } from "../../config/sessions.js";
|
|
6
|
+
import { createInternalHookEvent, triggerInternalHook } from "../../hooks/internal-hooks.js";
|
|
7
|
+
import { getAgentScopedMediaLocalRoots } from "../../media/local-roots.js";
|
|
8
|
+
import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js";
|
|
5
9
|
import { markdownToSignalTextChunks } from "../../signal/format.js";
|
|
6
10
|
import { sendMessageSignal } from "../../signal/send.js";
|
|
7
|
-
import {
|
|
11
|
+
import { throwIfAborted } from "./abort.js";
|
|
12
|
+
import { ackDelivery, enqueueDelivery, failDelivery } from "./delivery-queue.js";
|
|
8
13
|
import { normalizeReplyPayloadsForDelivery } from "./payloads.js";
|
|
9
14
|
export { normalizeOutboundPayloads } from "./payloads.js";
|
|
10
|
-
function throwIfAborted(abortSignal) {
|
|
11
|
-
if (abortSignal?.aborted) {
|
|
12
|
-
throw new Error("Outbound delivery aborted");
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
15
|
// Channel docking: outbound delivery delegates to plugin.outbound adapters.
|
|
16
16
|
async function createChannelHandler(params) {
|
|
17
17
|
const outbound = await loadChannelOutboundAdapter(params.channel);
|
|
18
|
-
|
|
19
|
-
throw new Error(`Outbound not configured for channel: ${params.channel}`);
|
|
20
|
-
}
|
|
21
|
-
const handler = createPluginHandler({
|
|
22
|
-
outbound,
|
|
23
|
-
cfg: params.cfg,
|
|
24
|
-
channel: params.channel,
|
|
25
|
-
to: params.to,
|
|
26
|
-
accountId: params.accountId,
|
|
27
|
-
replyToId: params.replyToId,
|
|
28
|
-
threadId: params.threadId,
|
|
29
|
-
deps: params.deps,
|
|
30
|
-
gifPlayback: params.gifPlayback,
|
|
31
|
-
});
|
|
18
|
+
const handler = createPluginHandler({ ...params, outbound });
|
|
32
19
|
if (!handler) {
|
|
33
20
|
throw new Error(`Outbound not configured for channel: ${params.channel}`);
|
|
34
21
|
}
|
|
@@ -36,59 +23,120 @@ async function createChannelHandler(params) {
|
|
|
36
23
|
}
|
|
37
24
|
function createPluginHandler(params) {
|
|
38
25
|
const outbound = params.outbound;
|
|
39
|
-
if (!outbound?.sendText || !outbound?.sendMedia)
|
|
26
|
+
if (!outbound?.sendText || !outbound?.sendMedia) {
|
|
40
27
|
return null;
|
|
28
|
+
}
|
|
29
|
+
const baseCtx = createChannelOutboundContextBase(params);
|
|
41
30
|
const sendText = outbound.sendText;
|
|
42
31
|
const sendMedia = outbound.sendMedia;
|
|
43
32
|
const chunker = outbound.chunker ?? null;
|
|
44
33
|
const chunkerMode = outbound.chunkerMode;
|
|
34
|
+
const resolveCtx = (overrides) => ({
|
|
35
|
+
...baseCtx,
|
|
36
|
+
replyToId: overrides?.replyToId ?? baseCtx.replyToId,
|
|
37
|
+
threadId: overrides?.threadId ?? baseCtx.threadId,
|
|
38
|
+
});
|
|
45
39
|
return {
|
|
46
40
|
chunker,
|
|
47
41
|
chunkerMode,
|
|
48
42
|
textChunkLimit: outbound.textChunkLimit,
|
|
49
43
|
sendPayload: outbound.sendPayload
|
|
50
|
-
? async (payload) => outbound.sendPayload({
|
|
51
|
-
|
|
52
|
-
to: params.to,
|
|
44
|
+
? async (payload, overrides) => outbound.sendPayload({
|
|
45
|
+
...resolveCtx(overrides),
|
|
53
46
|
text: payload.text ?? "",
|
|
54
47
|
mediaUrl: payload.mediaUrl,
|
|
55
|
-
accountId: params.accountId,
|
|
56
|
-
replyToId: params.replyToId,
|
|
57
|
-
threadId: params.threadId,
|
|
58
|
-
gifPlayback: params.gifPlayback,
|
|
59
|
-
deps: params.deps,
|
|
60
48
|
payload,
|
|
61
49
|
})
|
|
62
50
|
: undefined,
|
|
63
|
-
sendText: async (text) => sendText({
|
|
64
|
-
|
|
65
|
-
to: params.to,
|
|
51
|
+
sendText: async (text, overrides) => sendText({
|
|
52
|
+
...resolveCtx(overrides),
|
|
66
53
|
text,
|
|
67
|
-
accountId: params.accountId,
|
|
68
|
-
replyToId: params.replyToId,
|
|
69
|
-
threadId: params.threadId,
|
|
70
|
-
gifPlayback: params.gifPlayback,
|
|
71
|
-
deps: params.deps,
|
|
72
54
|
}),
|
|
73
|
-
sendMedia: async (caption, mediaUrl) => sendMedia({
|
|
74
|
-
|
|
75
|
-
to: params.to,
|
|
55
|
+
sendMedia: async (caption, mediaUrl, overrides) => sendMedia({
|
|
56
|
+
...resolveCtx(overrides),
|
|
76
57
|
text: caption,
|
|
77
58
|
mediaUrl,
|
|
78
|
-
accountId: params.accountId,
|
|
79
|
-
replyToId: params.replyToId,
|
|
80
|
-
threadId: params.threadId,
|
|
81
|
-
gifPlayback: params.gifPlayback,
|
|
82
|
-
deps: params.deps,
|
|
83
59
|
}),
|
|
84
60
|
};
|
|
85
61
|
}
|
|
62
|
+
function createChannelOutboundContextBase(params) {
|
|
63
|
+
return {
|
|
64
|
+
cfg: params.cfg,
|
|
65
|
+
to: params.to,
|
|
66
|
+
accountId: params.accountId,
|
|
67
|
+
replyToId: params.replyToId,
|
|
68
|
+
threadId: params.threadId,
|
|
69
|
+
identity: params.identity,
|
|
70
|
+
gifPlayback: params.gifPlayback,
|
|
71
|
+
deps: params.deps,
|
|
72
|
+
silent: params.silent,
|
|
73
|
+
mediaLocalRoots: params.mediaLocalRoots,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const isAbortError = (err) => err instanceof Error && err.name === "AbortError";
|
|
86
77
|
export async function deliverOutboundPayloads(params) {
|
|
78
|
+
const { channel, to, payloads } = params;
|
|
79
|
+
// Write-ahead delivery queue: persist before sending, remove after success.
|
|
80
|
+
const queueId = params.skipQueue
|
|
81
|
+
? null
|
|
82
|
+
: await enqueueDelivery({
|
|
83
|
+
channel,
|
|
84
|
+
to,
|
|
85
|
+
accountId: params.accountId,
|
|
86
|
+
payloads,
|
|
87
|
+
threadId: params.threadId,
|
|
88
|
+
replyToId: params.replyToId,
|
|
89
|
+
bestEffort: params.bestEffort,
|
|
90
|
+
gifPlayback: params.gifPlayback,
|
|
91
|
+
silent: params.silent,
|
|
92
|
+
mirror: params.mirror,
|
|
93
|
+
}).catch(() => null); // Best-effort — don't block delivery if queue write fails.
|
|
94
|
+
// Wrap onError to detect partial failures under bestEffort mode.
|
|
95
|
+
// When bestEffort is true, per-payload errors are caught and passed to onError
|
|
96
|
+
// without throwing — so the outer try/catch never fires. We track whether any
|
|
97
|
+
// payload failed so we can call failDelivery instead of ackDelivery.
|
|
98
|
+
let hadPartialFailure = false;
|
|
99
|
+
const wrappedParams = params.onError
|
|
100
|
+
? {
|
|
101
|
+
...params,
|
|
102
|
+
onError: (err, payload) => {
|
|
103
|
+
hadPartialFailure = true;
|
|
104
|
+
params.onError(err, payload);
|
|
105
|
+
},
|
|
106
|
+
}
|
|
107
|
+
: params;
|
|
108
|
+
try {
|
|
109
|
+
const results = await deliverOutboundPayloadsCore(wrappedParams);
|
|
110
|
+
if (queueId) {
|
|
111
|
+
if (hadPartialFailure) {
|
|
112
|
+
await failDelivery(queueId, "partial delivery failure (bestEffort)").catch(() => { });
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
await ackDelivery(queueId).catch(() => { }); // Best-effort cleanup.
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return results;
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
if (queueId) {
|
|
122
|
+
if (isAbortError(err)) {
|
|
123
|
+
await ackDelivery(queueId).catch(() => { });
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
await failDelivery(queueId, err instanceof Error ? err.message : String(err)).catch(() => { });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
throw err;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/** Core delivery logic (extracted for queue wrapper). */
|
|
133
|
+
async function deliverOutboundPayloadsCore(params) {
|
|
87
134
|
const { cfg, channel, to, payloads } = params;
|
|
88
135
|
const accountId = params.accountId;
|
|
89
136
|
const deps = params.deps;
|
|
90
137
|
const abortSignal = params.abortSignal;
|
|
91
138
|
const sendSignal = params.deps?.sendSignal ?? sendMessageSignal;
|
|
139
|
+
const mediaLocalRoots = getAgentScopedMediaLocalRoots(cfg, params.agentId ?? params.mirror?.agentId);
|
|
92
140
|
const results = [];
|
|
93
141
|
const handler = await createChannelHandler({
|
|
94
142
|
cfg,
|
|
@@ -98,7 +146,10 @@ export async function deliverOutboundPayloads(params) {
|
|
|
98
146
|
accountId,
|
|
99
147
|
replyToId: params.replyToId,
|
|
100
148
|
threadId: params.threadId,
|
|
149
|
+
identity: params.identity,
|
|
101
150
|
gifPlayback: params.gifPlayback,
|
|
151
|
+
silent: params.silent,
|
|
152
|
+
mediaLocalRoots,
|
|
102
153
|
});
|
|
103
154
|
const textLimit = handler.chunker
|
|
104
155
|
? resolveTextChunkLimit(cfg, channel, accountId, {
|
|
@@ -118,10 +169,10 @@ export async function deliverOutboundPayloads(params) {
|
|
|
118
169
|
accountId,
|
|
119
170
|
})
|
|
120
171
|
: undefined;
|
|
121
|
-
const sendTextChunks = async (text) => {
|
|
172
|
+
const sendTextChunks = async (text, overrides) => {
|
|
122
173
|
throwIfAborted(abortSignal);
|
|
123
174
|
if (!handler.chunker || textLimit === undefined) {
|
|
124
|
-
results.push(await handler.sendText(text));
|
|
175
|
+
results.push(await handler.sendText(text, overrides));
|
|
125
176
|
return;
|
|
126
177
|
}
|
|
127
178
|
if (chunkMode === "newline") {
|
|
@@ -129,15 +180,17 @@ export async function deliverOutboundPayloads(params) {
|
|
|
129
180
|
const blockChunks = mode === "markdown"
|
|
130
181
|
? chunkMarkdownTextWithMode(text, textLimit, "newline")
|
|
131
182
|
: chunkByParagraph(text, textLimit);
|
|
132
|
-
if (!blockChunks.length && text)
|
|
183
|
+
if (!blockChunks.length && text) {
|
|
133
184
|
blockChunks.push(text);
|
|
185
|
+
}
|
|
134
186
|
for (const blockChunk of blockChunks) {
|
|
135
187
|
const chunks = handler.chunker(blockChunk, textLimit);
|
|
136
|
-
if (!chunks.length && blockChunk)
|
|
188
|
+
if (!chunks.length && blockChunk) {
|
|
137
189
|
chunks.push(blockChunk);
|
|
190
|
+
}
|
|
138
191
|
for (const chunk of chunks) {
|
|
139
192
|
throwIfAborted(abortSignal);
|
|
140
|
-
results.push(await handler.sendText(chunk));
|
|
193
|
+
results.push(await handler.sendText(chunk, overrides));
|
|
141
194
|
}
|
|
142
195
|
}
|
|
143
196
|
return;
|
|
@@ -145,7 +198,7 @@ export async function deliverOutboundPayloads(params) {
|
|
|
145
198
|
const chunks = handler.chunker(text, textLimit);
|
|
146
199
|
for (const chunk of chunks) {
|
|
147
200
|
throwIfAborted(abortSignal);
|
|
148
|
-
results.push(await handler.sendText(chunk));
|
|
201
|
+
results.push(await handler.sendText(chunk, overrides));
|
|
149
202
|
}
|
|
150
203
|
};
|
|
151
204
|
const sendSignalText = async (text, styles) => {
|
|
@@ -191,48 +244,161 @@ export async function deliverOutboundPayloads(params) {
|
|
|
191
244
|
accountId: accountId ?? undefined,
|
|
192
245
|
textMode: "plain",
|
|
193
246
|
textStyles: formatted.styles,
|
|
247
|
+
mediaLocalRoots,
|
|
194
248
|
})),
|
|
195
249
|
};
|
|
196
250
|
};
|
|
197
|
-
const
|
|
251
|
+
const normalizeWhatsAppPayload = (payload) => {
|
|
252
|
+
const hasMedia = Boolean(payload.mediaUrl) || (payload.mediaUrls?.length ?? 0) > 0;
|
|
253
|
+
const rawText = typeof payload.text === "string" ? payload.text : "";
|
|
254
|
+
const normalizedText = rawText.replace(/^(?:[ \t]*\r?\n)+/, "");
|
|
255
|
+
if (!normalizedText.trim()) {
|
|
256
|
+
if (!hasMedia) {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
...payload,
|
|
261
|
+
text: "",
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
return {
|
|
265
|
+
...payload,
|
|
266
|
+
text: normalizedText,
|
|
267
|
+
};
|
|
268
|
+
};
|
|
269
|
+
const normalizedPayloads = normalizeReplyPayloadsForDelivery(payloads).flatMap((payload) => {
|
|
270
|
+
if (channel !== "whatsapp") {
|
|
271
|
+
return [payload];
|
|
272
|
+
}
|
|
273
|
+
const normalized = normalizeWhatsAppPayload(payload);
|
|
274
|
+
return normalized ? [normalized] : [];
|
|
275
|
+
});
|
|
276
|
+
const hookRunner = getGlobalHookRunner();
|
|
277
|
+
const sessionKeyForInternalHooks = params.mirror?.sessionKey;
|
|
198
278
|
for (const payload of normalizedPayloads) {
|
|
199
279
|
const payloadSummary = {
|
|
200
280
|
text: payload.text ?? "",
|
|
201
281
|
mediaUrls: payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []),
|
|
202
282
|
channelData: payload.channelData,
|
|
203
283
|
};
|
|
284
|
+
const emitMessageSent = (params) => {
|
|
285
|
+
if (hookRunner?.hasHooks("message_sent")) {
|
|
286
|
+
void hookRunner
|
|
287
|
+
.runMessageSent({
|
|
288
|
+
to,
|
|
289
|
+
content: params.content,
|
|
290
|
+
success: params.success,
|
|
291
|
+
...(params.error ? { error: params.error } : {}),
|
|
292
|
+
}, {
|
|
293
|
+
channelId: channel,
|
|
294
|
+
accountId: accountId ?? undefined,
|
|
295
|
+
conversationId: to,
|
|
296
|
+
})
|
|
297
|
+
.catch(() => { });
|
|
298
|
+
}
|
|
299
|
+
if (!sessionKeyForInternalHooks) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
void triggerInternalHook(createInternalHookEvent("message", "sent", sessionKeyForInternalHooks, {
|
|
303
|
+
to,
|
|
304
|
+
content: params.content,
|
|
305
|
+
success: params.success,
|
|
306
|
+
...(params.error ? { error: params.error } : {}),
|
|
307
|
+
channelId: channel,
|
|
308
|
+
accountId: accountId ?? undefined,
|
|
309
|
+
conversationId: to,
|
|
310
|
+
messageId: params.messageId,
|
|
311
|
+
})).catch(() => { });
|
|
312
|
+
};
|
|
204
313
|
try {
|
|
205
314
|
throwIfAborted(abortSignal);
|
|
315
|
+
// Run message_sending plugin hook (may modify content or cancel)
|
|
316
|
+
let effectivePayload = payload;
|
|
317
|
+
if (hookRunner?.hasHooks("message_sending")) {
|
|
318
|
+
try {
|
|
319
|
+
const sendingResult = await hookRunner.runMessageSending({
|
|
320
|
+
to,
|
|
321
|
+
content: payloadSummary.text,
|
|
322
|
+
metadata: { channel, accountId, mediaUrls: payloadSummary.mediaUrls },
|
|
323
|
+
}, {
|
|
324
|
+
channelId: channel,
|
|
325
|
+
accountId: accountId ?? undefined,
|
|
326
|
+
});
|
|
327
|
+
if (sendingResult?.cancel) {
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
if (sendingResult?.content != null) {
|
|
331
|
+
effectivePayload = { ...payload, text: sendingResult.content };
|
|
332
|
+
payloadSummary.text = sendingResult.content;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
catch {
|
|
336
|
+
// Don't block delivery on hook failure
|
|
337
|
+
}
|
|
338
|
+
}
|
|
206
339
|
params.onPayload?.(payloadSummary);
|
|
207
|
-
|
|
208
|
-
|
|
340
|
+
const sendOverrides = {
|
|
341
|
+
replyToId: effectivePayload.replyToId ?? params.replyToId ?? undefined,
|
|
342
|
+
threadId: params.threadId ?? undefined,
|
|
343
|
+
};
|
|
344
|
+
if (handler.sendPayload && effectivePayload.channelData) {
|
|
345
|
+
const delivery = await handler.sendPayload(effectivePayload, sendOverrides);
|
|
346
|
+
results.push(delivery);
|
|
347
|
+
emitMessageSent({
|
|
348
|
+
success: true,
|
|
349
|
+
content: payloadSummary.text,
|
|
350
|
+
messageId: delivery.messageId,
|
|
351
|
+
});
|
|
209
352
|
continue;
|
|
210
353
|
}
|
|
211
354
|
if (payloadSummary.mediaUrls.length === 0) {
|
|
355
|
+
const beforeCount = results.length;
|
|
212
356
|
if (isSignalChannel) {
|
|
213
357
|
await sendSignalTextChunks(payloadSummary.text);
|
|
214
358
|
}
|
|
215
359
|
else {
|
|
216
|
-
await sendTextChunks(payloadSummary.text);
|
|
360
|
+
await sendTextChunks(payloadSummary.text, sendOverrides);
|
|
217
361
|
}
|
|
362
|
+
const messageId = results.at(-1)?.messageId;
|
|
363
|
+
emitMessageSent({
|
|
364
|
+
success: results.length > beforeCount,
|
|
365
|
+
content: payloadSummary.text,
|
|
366
|
+
messageId,
|
|
367
|
+
});
|
|
218
368
|
continue;
|
|
219
369
|
}
|
|
220
370
|
let first = true;
|
|
371
|
+
let lastMessageId;
|
|
221
372
|
for (const url of payloadSummary.mediaUrls) {
|
|
222
373
|
throwIfAborted(abortSignal);
|
|
223
374
|
const caption = first ? payloadSummary.text : "";
|
|
224
375
|
first = false;
|
|
225
376
|
if (isSignalChannel) {
|
|
226
|
-
|
|
377
|
+
const delivery = await sendSignalMedia(caption, url);
|
|
378
|
+
results.push(delivery);
|
|
379
|
+
lastMessageId = delivery.messageId;
|
|
227
380
|
}
|
|
228
381
|
else {
|
|
229
|
-
|
|
382
|
+
const delivery = await handler.sendMedia(caption, url, sendOverrides);
|
|
383
|
+
results.push(delivery);
|
|
384
|
+
lastMessageId = delivery.messageId;
|
|
230
385
|
}
|
|
231
386
|
}
|
|
387
|
+
emitMessageSent({
|
|
388
|
+
success: true,
|
|
389
|
+
content: payloadSummary.text,
|
|
390
|
+
messageId: lastMessageId,
|
|
391
|
+
});
|
|
232
392
|
}
|
|
233
393
|
catch (err) {
|
|
234
|
-
|
|
394
|
+
emitMessageSent({
|
|
395
|
+
success: false,
|
|
396
|
+
content: payloadSummary.text,
|
|
397
|
+
error: err instanceof Error ? err.message : String(err),
|
|
398
|
+
});
|
|
399
|
+
if (!params.bestEffort) {
|
|
235
400
|
throw err;
|
|
401
|
+
}
|
|
236
402
|
params.onError?.(err, payloadSummary);
|
|
237
403
|
}
|
|
238
404
|
}
|
|
@@ -42,12 +42,14 @@ export const MESSAGE_ACTION_TARGET_MODE = {
|
|
|
42
42
|
"category-create": "none",
|
|
43
43
|
"category-edit": "none",
|
|
44
44
|
"category-delete": "none",
|
|
45
|
+
"topic-create": "to",
|
|
45
46
|
"voice-status": "none",
|
|
46
47
|
"event-list": "none",
|
|
47
48
|
"event-create": "none",
|
|
48
49
|
timeout: "none",
|
|
49
50
|
kick: "none",
|
|
50
51
|
ban: "none",
|
|
52
|
+
"set-presence": "none",
|
|
51
53
|
};
|
|
52
54
|
const ACTION_TARGET_ALIASES = {
|
|
53
55
|
unsend: ["messageId"],
|
|
@@ -64,20 +66,25 @@ export function actionRequiresTarget(action) {
|
|
|
64
66
|
}
|
|
65
67
|
export function actionHasTarget(action, params) {
|
|
66
68
|
const to = typeof params.to === "string" ? params.to.trim() : "";
|
|
67
|
-
if (to)
|
|
69
|
+
if (to) {
|
|
68
70
|
return true;
|
|
71
|
+
}
|
|
69
72
|
const channelId = typeof params.channelId === "string" ? params.channelId.trim() : "";
|
|
70
|
-
if (channelId)
|
|
73
|
+
if (channelId) {
|
|
71
74
|
return true;
|
|
75
|
+
}
|
|
72
76
|
const aliases = ACTION_TARGET_ALIASES[action];
|
|
73
|
-
if (!aliases)
|
|
77
|
+
if (!aliases) {
|
|
74
78
|
return false;
|
|
79
|
+
}
|
|
75
80
|
return aliases.some((alias) => {
|
|
76
81
|
const value = params[alias];
|
|
77
|
-
if (typeof value === "string")
|
|
82
|
+
if (typeof value === "string") {
|
|
78
83
|
return value.trim().length > 0;
|
|
79
|
-
|
|
84
|
+
}
|
|
85
|
+
if (typeof value === "number") {
|
|
80
86
|
return Number.isFinite(value);
|
|
87
|
+
}
|
|
81
88
|
return false;
|
|
82
89
|
});
|
|
83
90
|
}
|
|
@@ -2,7 +2,7 @@ import { getChannelPlugin } from "../../channels/plugins/index.js";
|
|
|
2
2
|
import { recordSessionMetaFromInbound, resolveStorePath } from "../../config/sessions.js";
|
|
3
3
|
import { parseDiscordTarget } from "../../discord/targets.js";
|
|
4
4
|
import { parseIMessageTarget, normalizeIMessageHandle } from "../../imessage/targets.js";
|
|
5
|
-
import { buildAgentSessionKey
|
|
5
|
+
import { buildAgentSessionKey } from "../../routing/resolve-route.js";
|
|
6
6
|
import { resolveThreadSessionKeys } from "../../routing/session-key.js";
|
|
7
7
|
import { resolveSignalPeerId, resolveSignalRecipient, resolveSignalSender, } from "../../signal/identity.js";
|
|
8
8
|
import { resolveSlackAccount } from "../../slack/accounts.js";
|
|
@@ -55,7 +55,7 @@ function stripKindPrefix(raw) {
|
|
|
55
55
|
function inferPeerKind(params) {
|
|
56
56
|
const resolvedKind = params.resolvedTarget?.kind;
|
|
57
57
|
if (resolvedKind === "user") {
|
|
58
|
-
return "
|
|
58
|
+
return "direct";
|
|
59
59
|
}
|
|
60
60
|
if (resolvedKind === "channel") {
|
|
61
61
|
return "channel";
|
|
@@ -70,7 +70,7 @@ function inferPeerKind(params) {
|
|
|
70
70
|
}
|
|
71
71
|
return "group";
|
|
72
72
|
}
|
|
73
|
-
return "
|
|
73
|
+
return "direct";
|
|
74
74
|
}
|
|
75
75
|
function buildBaseSessionKey(params) {
|
|
76
76
|
return buildAgentSessionKey({
|
|
@@ -138,7 +138,7 @@ async function resolveSlackSession(params) {
|
|
|
138
138
|
return null;
|
|
139
139
|
}
|
|
140
140
|
const isDm = parsed.kind === "user";
|
|
141
|
-
let peerKind = isDm ? "
|
|
141
|
+
let peerKind = isDm ? "direct" : "channel";
|
|
142
142
|
if (!isDm && /^G/i.test(parsed.id)) {
|
|
143
143
|
// Slack mpim/group DMs share the G-prefix; detect to align session keys with inbound.
|
|
144
144
|
const channelType = await resolveSlackChannelType({
|
|
@@ -150,7 +150,7 @@ async function resolveSlackSession(params) {
|
|
|
150
150
|
peerKind = "group";
|
|
151
151
|
}
|
|
152
152
|
if (channelType === "dm") {
|
|
153
|
-
peerKind = "
|
|
153
|
+
peerKind = "direct";
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
const peer = {
|
|
@@ -173,13 +173,13 @@ async function resolveSlackSession(params) {
|
|
|
173
173
|
sessionKey: threadKeys.sessionKey,
|
|
174
174
|
baseSessionKey,
|
|
175
175
|
peer,
|
|
176
|
-
chatType: peerKind === "
|
|
177
|
-
from: peerKind === "
|
|
176
|
+
chatType: peerKind === "direct" ? "direct" : "channel",
|
|
177
|
+
from: peerKind === "direct"
|
|
178
178
|
? `slack:${parsed.id}`
|
|
179
179
|
: peerKind === "group"
|
|
180
180
|
? `slack:group:${parsed.id}`
|
|
181
181
|
: `slack:channel:${parsed.id}`,
|
|
182
|
-
to: peerKind === "
|
|
182
|
+
to: peerKind === "direct" ? `user:${parsed.id}` : `channel:${parsed.id}`,
|
|
183
183
|
threadId,
|
|
184
184
|
};
|
|
185
185
|
}
|
|
@@ -190,7 +190,7 @@ function resolveDiscordSession(params) {
|
|
|
190
190
|
}
|
|
191
191
|
const isDm = parsed.kind === "user";
|
|
192
192
|
const peer = {
|
|
193
|
-
kind: isDm ? "
|
|
193
|
+
kind: isDm ? "direct" : "channel",
|
|
194
194
|
id: parsed.id,
|
|
195
195
|
};
|
|
196
196
|
const baseSessionKey = buildBaseSessionKey({
|
|
@@ -236,7 +236,7 @@ function resolveTelegramSession(params) {
|
|
|
236
236
|
params.resolvedTarget.kind !== "user");
|
|
237
237
|
const peerId = isGroup ? buildTelegramGroupPeerId(chatId, resolvedThreadId) : chatId;
|
|
238
238
|
const peer = {
|
|
239
|
-
kind: isGroup ? "group" : "
|
|
239
|
+
kind: isGroup ? "group" : "direct",
|
|
240
240
|
id: peerId,
|
|
241
241
|
};
|
|
242
242
|
const baseSessionKey = buildBaseSessionKey({
|
|
@@ -263,7 +263,7 @@ function resolveWhatsAppSession(params) {
|
|
|
263
263
|
}
|
|
264
264
|
const isGroup = isWhatsAppGroupJid(normalized);
|
|
265
265
|
const peer = {
|
|
266
|
-
kind: isGroup ? "group" : "
|
|
266
|
+
kind: isGroup ? "group" : "direct",
|
|
267
267
|
id: normalized,
|
|
268
268
|
};
|
|
269
269
|
const baseSessionKey = buildBaseSessionKey({
|
|
@@ -326,7 +326,7 @@ function resolveSignalSession(params) {
|
|
|
326
326
|
});
|
|
327
327
|
const peerId = sender ? resolveSignalPeerId(sender) : recipient;
|
|
328
328
|
const displayRecipient = sender ? resolveSignalRecipient(sender) : recipient;
|
|
329
|
-
const peer = { kind: "
|
|
329
|
+
const peer = { kind: "direct", id: peerId };
|
|
330
330
|
const baseSessionKey = buildBaseSessionKey({
|
|
331
331
|
cfg: params.cfg,
|
|
332
332
|
agentId: params.agentId,
|
|
@@ -350,7 +350,7 @@ function resolveIMessageSession(params) {
|
|
|
350
350
|
if (!handle) {
|
|
351
351
|
return null;
|
|
352
352
|
}
|
|
353
|
-
const peer = { kind: "
|
|
353
|
+
const peer = { kind: "direct", id: handle };
|
|
354
354
|
const baseSessionKey = buildBaseSessionKey({
|
|
355
355
|
cfg: params.cfg,
|
|
356
356
|
agentId: params.agentId,
|
|
@@ -404,7 +404,7 @@ function resolveMatrixSession(params) {
|
|
|
404
404
|
if (!rawId) {
|
|
405
405
|
return null;
|
|
406
406
|
}
|
|
407
|
-
const peer = { kind: isUser ? "
|
|
407
|
+
const peer = { kind: isUser ? "direct" : "channel", id: rawId };
|
|
408
408
|
const baseSessionKey = buildBaseSessionKey({
|
|
409
409
|
cfg: params.cfg,
|
|
410
410
|
agentId: params.agentId,
|
|
@@ -436,7 +436,7 @@ function resolveMSTeamsSession(params) {
|
|
|
436
436
|
const conversationId = rawId.split(";")[0] ?? rawId;
|
|
437
437
|
const isChannel = !isUser && /@thread\.tacv2/i.test(conversationId);
|
|
438
438
|
const peer = {
|
|
439
|
-
kind: isUser ? "
|
|
439
|
+
kind: isUser ? "direct" : isChannel ? "channel" : "group",
|
|
440
440
|
id: conversationId,
|
|
441
441
|
};
|
|
442
442
|
const baseSessionKey = buildBaseSessionKey({
|
|
@@ -474,7 +474,7 @@ function resolveMattermostSession(params) {
|
|
|
474
474
|
if (!rawId) {
|
|
475
475
|
return null;
|
|
476
476
|
}
|
|
477
|
-
const peer = { kind: isUser ? "
|
|
477
|
+
const peer = { kind: isUser ? "direct" : "channel", id: rawId };
|
|
478
478
|
const baseSessionKey = buildBaseSessionKey({
|
|
479
479
|
cfg: params.cfg,
|
|
480
480
|
agentId: params.agentId,
|
|
@@ -515,7 +515,7 @@ function resolveBlueBubblesSession(params) {
|
|
|
515
515
|
return null;
|
|
516
516
|
}
|
|
517
517
|
const peer = {
|
|
518
|
-
kind: isGroup ? "group" : "
|
|
518
|
+
kind: isGroup ? "group" : "direct",
|
|
519
519
|
id: peerId,
|
|
520
520
|
};
|
|
521
521
|
const baseSessionKey = buildBaseSessionKey({
|
|
@@ -570,7 +570,7 @@ function resolveZaloSession(params) {
|
|
|
570
570
|
}
|
|
571
571
|
const isGroup = trimmed.toLowerCase().startsWith("group:");
|
|
572
572
|
const peerId = stripKindPrefix(trimmed);
|
|
573
|
-
const peer = { kind: isGroup ? "group" : "
|
|
573
|
+
const peer = { kind: isGroup ? "group" : "direct", id: peerId };
|
|
574
574
|
const baseSessionKey = buildBaseSessionKey({
|
|
575
575
|
cfg: params.cfg,
|
|
576
576
|
agentId: params.agentId,
|
|
@@ -597,7 +597,7 @@ function resolveZalouserSession(params) {
|
|
|
597
597
|
const isGroup = trimmed.toLowerCase().startsWith("group:");
|
|
598
598
|
const peerId = stripKindPrefix(trimmed);
|
|
599
599
|
// Keep DM vs group aligned with inbound sessions for Zalo Personal.
|
|
600
|
-
const peer = { kind: isGroup ? "group" : "
|
|
600
|
+
const peer = { kind: isGroup ? "group" : "direct", id: peerId };
|
|
601
601
|
const baseSessionKey = buildBaseSessionKey({
|
|
602
602
|
cfg: params.cfg,
|
|
603
603
|
agentId: params.agentId,
|
|
@@ -619,7 +619,7 @@ function resolveNostrSession(params) {
|
|
|
619
619
|
if (!trimmed) {
|
|
620
620
|
return null;
|
|
621
621
|
}
|
|
622
|
-
const peer = { kind: "
|
|
622
|
+
const peer = { kind: "direct", id: trimmed };
|
|
623
623
|
const baseSessionKey = buildBaseSessionKey({
|
|
624
624
|
cfg: params.cfg,
|
|
625
625
|
agentId: params.agentId,
|
|
@@ -680,7 +680,7 @@ function resolveTlonSession(params) {
|
|
|
680
680
|
else {
|
|
681
681
|
peerId = normalizeTlonShip(trimmed);
|
|
682
682
|
}
|
|
683
|
-
const peer = { kind: isGroup ? "group" : "
|
|
683
|
+
const peer = { kind: isGroup ? "group" : "direct", id: peerId };
|
|
684
684
|
const baseSessionKey = buildBaseSessionKey({
|
|
685
685
|
cfg: params.cfg,
|
|
686
686
|
agentId: params.agentId,
|
|
@@ -728,7 +728,7 @@ function resolveFeishuSession(params) {
|
|
|
728
728
|
isGroup = false;
|
|
729
729
|
}
|
|
730
730
|
const peer = {
|
|
731
|
-
kind: isGroup ? "group" : "
|
|
731
|
+
kind: isGroup ? "group" : "direct",
|
|
732
732
|
id: trimmed,
|
|
733
733
|
};
|
|
734
734
|
const baseSessionKey = buildBaseSessionKey({
|
|
@@ -767,9 +767,11 @@ function resolveFallbackSession(params) {
|
|
|
767
767
|
channel: params.channel,
|
|
768
768
|
peer,
|
|
769
769
|
});
|
|
770
|
-
const chatType = peerKind === "
|
|
771
|
-
const from = peerKind === "
|
|
772
|
-
|
|
770
|
+
const chatType = peerKind === "direct" ? "direct" : peerKind === "channel" ? "channel" : "group";
|
|
771
|
+
const from = peerKind === "direct"
|
|
772
|
+
? `${params.channel}:${peerId}`
|
|
773
|
+
: `${params.channel}:${peerKind}:${peerId}`;
|
|
774
|
+
const toPrefix = peerKind === "direct" ? "user" : "channel";
|
|
773
775
|
return {
|
|
774
776
|
sessionKey: baseSessionKey,
|
|
775
777
|
baseSessionKey,
|