@openclaw/imessage 2026.8.1-beta.2 → 2026.8.1-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{actions.runtime-DTFKDN5p.js → actions.runtime-B_xJiBXF.js} +3 -3
- package/dist/api.js +4 -4
- package/dist/{approval-handler.runtime-BtLs4gho.js → approval-handler.runtime-BKku8aUf.js} +14 -8
- package/dist/approval-reactions-BME5eA6T.js +566 -0
- package/dist/{catchup-D32oYNxR.js → catchup-Dh-Rv4Ur.js} +1 -1
- package/dist/{channel-lppmI51h.js → channel-BFQTpvrG.js} +18 -14
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-5wpCKQb7.js → channel.runtime-BjkXwX9_.js} +3 -3
- package/dist/doctor-contract-api.js +3 -3
- package/dist/{group-policy-DF9xSdik.js → group-policy-Ca3c5KES.js} +12 -639
- package/dist/{message-tool-api-CPDfJJoE.js → message-tool-api-TZiNYA17.js} +5 -2
- package/dist/message-tool-api.js +1 -1
- package/dist/{monitor-DnxJ8pW9.js → monitor-Uv5RaRTk.js} +65 -94
- package/dist/{monitor-reply-cache-DKlYGd5x.js → monitor-reply-cache-BdeUQaHO.js} +6 -1
- package/dist/{persisted-echo-cache-BPWGUK-L.js → persisted-echo-cache-DGxy-J4t.js} +1 -1
- package/dist/{question-reactions-DVe50UhB.js → question-reactions-to0i8vxE.js} +2 -1
- package/dist/reaction-context-DaNrZqYo.js +105 -0
- package/dist/{remote-file-DLwO9ved.js → remote-file-CDuk0joc.js} +6 -2
- package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/runtime-api.js +4 -4
- package/dist/{sanitize-outbound-CoTZLXMw.js → sanitize-outbound-DaLmdkbf.js} +1 -1
- package/dist/{send-BUXW76tw.js → send-Dake4Awx.js} +22 -22
- package/package.json +4 -4
|
@@ -77,6 +77,9 @@ function setCachedIMessagePrivateApiStatus(cliPath, status, expiresAt = 0) {
|
|
|
77
77
|
//#endregion
|
|
78
78
|
//#region extensions/imessage/src/target-identifiers.ts
|
|
79
79
|
const BARE_CHAT_IDENTIFIER_RE = /^[0-9a-f]{32}$/i;
|
|
80
|
+
function isIMessagePhoneLikeHandle(raw) {
|
|
81
|
+
return /^(?:tel:)?[+\d\s().-]+$/i.test(raw.trim());
|
|
82
|
+
}
|
|
80
83
|
function normalizeBareIMessageChatIdentifier(raw) {
|
|
81
84
|
const trimmed = raw.trim();
|
|
82
85
|
if (!BARE_CHAT_IDENTIFIER_RE.test(trimmed)) return;
|
|
@@ -136,7 +139,7 @@ function normalizeIMessageHandle(raw) {
|
|
|
136
139
|
if (trimmed.includes("@")) return normalizeLowercaseStringOrEmpty(trimmed);
|
|
137
140
|
const bareChatIdentifier = normalizeBareIMessageChatIdentifier(trimmed);
|
|
138
141
|
if (bareChatIdentifier) return `chat_identifier:${bareChatIdentifier}`;
|
|
139
|
-
const normalized = normalizeE164(trimmed);
|
|
142
|
+
const normalized = isIMessagePhoneLikeHandle(trimmed) ? normalizeE164(trimmed) : "";
|
|
140
143
|
if (normalized) return normalized;
|
|
141
144
|
return trimmed.replace(/\s+/g, "");
|
|
142
145
|
}
|
|
@@ -312,4 +315,4 @@ function describeIMessageMessageTool({ cfg, accountId, currentChannelId }) {
|
|
|
312
315
|
};
|
|
313
316
|
}
|
|
314
317
|
//#endregion
|
|
315
|
-
export { IMESSAGE_ACTION_NAMES as S,
|
|
318
|
+
export { IMESSAGE_ACTION_NAMES as C, IMESSAGE_ACTIONS as S, isIMessagePhoneLikeHandle as _, isAllowedIMessageSender as a, imessageRpcSupportsMethod as b, parseIMessageAllowTarget as c, parseChatAllowTargetPrefixes as d, parseChatTargetPrefixesOrThrow as f, resolveServicePrefixedTarget as g, resolveServicePrefixedOrChatAllowTarget as h, isAllowedIMessageReplyContextSender as i, parseIMessageTarget as l, resolveServicePrefixedChatTarget as m, formatIMessageChatTarget as n, looksLikeIMessageExplicitTargetId as o, resolveServicePrefixedAllowTarget as p, inferIMessageTargetChatType as r, normalizeIMessageHandle as s, describeIMessageMessageTool as t, createAllowedChatSenderMatcher as u, normalizeBareIMessageChatIdentifier as v, setCachedIMessagePrivateApiStatus as x, getCachedIMessagePrivateApiStatus as y };
|
package/dist/message-tool-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as describeIMessageMessageTool } from "./message-tool-api-
|
|
1
|
+
import { t as describeIMessageMessageTool } from "./message-tool-api-TZiNYA17.js";
|
|
2
2
|
export { describeIMessageMessageTool as describeMessageTool };
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { C as registerIMessageApprovalReactionTarget, D as buildIMessageApprovalConversationKeyForInbound, E as resolveIMessageReactionContext, I as probeIMessage, S as maybeResolveIMessageApprovalReaction, b as handleIMessageApprovalReaction, r as resolveIMessageInboundConversationId, x as listPendingIMessageApprovalReactionPollTargets, y as extractIMessageApprovalPromptBinding } from "./group-policy-DF9xSdik.js";
|
|
2
1
|
import { d as resolveIMessageChatDbLookupPath, f as resolveIMessageHomeDir, l as resolveIMessageRemoteHost, o as resolveIMessageAccount } from "./accounts-D00Njxg2.js";
|
|
3
|
-
import { c as parseIMessageAllowTarget, i as isAllowedIMessageReplyContextSender, l as parseIMessageTarget, n as formatIMessageChatTarget, s as normalizeIMessageHandle,
|
|
4
|
-
import { c as rememberIMessageReplyCache, f as getIMessageRuntime, s as isKnownFromMeIMessageMessageId } from "./monitor-reply-cache-
|
|
5
|
-
import { o as createIMessageRpcClient, r as sanitizeOutboundText } from "./sanitize-outbound-
|
|
2
|
+
import { b as imessageRpcSupportsMethod, c as parseIMessageAllowTarget, i as isAllowedIMessageReplyContextSender, l as parseIMessageTarget, n as formatIMessageChatTarget, s as normalizeIMessageHandle, y as getCachedIMessagePrivateApiStatus } from "./message-tool-api-TZiNYA17.js";
|
|
3
|
+
import { c as rememberIMessageReplyCache, f as getIMessageRuntime, s as isKnownFromMeIMessageMessageId, v as resolveIMessageDirectChatService } from "./monitor-reply-cache-BdeUQaHO.js";
|
|
4
|
+
import { o as createIMessageRpcClient, r as sanitizeOutboundText } from "./sanitize-outbound-DaLmdkbf.js";
|
|
5
|
+
import { r as resolveIMessageInboundConversationId, y as probeIMessage } from "./group-policy-Ca3c5KES.js";
|
|
6
6
|
import { n as resolveIMessageAttachmentRoots, r as resolveIMessageRemoteAttachmentRoots } from "./media-contract-BEgdvYhW.js";
|
|
7
|
-
import { a as resolveCatchupConfig, i as performIMessageCatchup, n as advanceIMessageCatchupCursor } from "./catchup-
|
|
8
|
-
import { c as stripLeadingEchoTextCorruptionMarkers, i as hasPersistedIMessageEcho, o as resolveIMessageEchoMediaKey } from "./persisted-echo-cache-
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
7
|
+
import { a as resolveCatchupConfig, i as performIMessageCatchup, n as advanceIMessageCatchupCursor } from "./catchup-Dh-Rv4Ur.js";
|
|
8
|
+
import { c as stripLeadingEchoTextCorruptionMarkers, i as hasPersistedIMessageEcho, o as resolveIMessageEchoMediaKey } from "./persisted-echo-cache-DGxy-J4t.js";
|
|
9
|
+
import { i as registerIMessageApprovalReactionTarget, n as handleIMessageApprovalReaction, o as listPendingIMessageApprovalReactionPollTargets, r as maybeResolveIMessageApprovalReaction, s as buildIMessageApprovalConversationKeyForInbound } from "./approval-reactions-BME5eA6T.js";
|
|
10
|
+
import { a as maybeResolveIMessageApprovalPollVote, o as iMessageApprovalControlBindings, t as sendMessageIMessage } from "./send-Dake4Awx.js";
|
|
11
|
+
import { t as resolveIMessageReactionContext } from "./reaction-context-DaNrZqYo.js";
|
|
12
|
+
import { n as maybeResolveIMessageQuestionReaction, t as hasIMessageQuestionReactionTarget } from "./question-reactions-to0i8vxE.js";
|
|
11
13
|
import { bindIngressLifecycleToReplyOptions, createChannelIngressError, createChannelIngressMonitor, createChannelMessageReplyPipeline, createMessageReceiptFromOutboundResults, listMessageReceiptPlatformIds, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
|
|
12
14
|
import { chunkMarkdownTextWithMode as chunkTextWithMode, resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
|
|
13
15
|
import { resolveAgentRoute, resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
|
|
@@ -16,7 +18,7 @@ import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
|
16
18
|
import { asSafeIntegerInRange, hasNonEmptyString, isRecord, normalizeOptionalString, normalizeStringEntries, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
17
19
|
import fs from "node:fs/promises";
|
|
18
20
|
import { createNonExitingRuntime, danger, logVerbose, shouldLogVerbose, warn } from "openclaw/plugin-sdk/runtime-env";
|
|
19
|
-
import { asDateTimestampMs, asPositiveFiniteNumber, parseDateStringTimestampMs,
|
|
21
|
+
import { asDateTimestampMs, asPositiveFiniteNumber, parseDateStringTimestampMs, timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
20
22
|
import { createHash } from "node:crypto";
|
|
21
23
|
import { getRuntimeConfig } from "openclaw/plugin-sdk/runtime-config-snapshot";
|
|
22
24
|
import { sliceUtf16Safe, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
@@ -33,7 +35,7 @@ import { logTypingFailure } from "openclaw/plugin-sdk/channel-feedback";
|
|
|
33
35
|
import { createChannelIngressResolver, defineStableChannelIngressIdentity, fanInChannelIngressLifecycles } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
34
36
|
import { createChannelPairingChallengeIssuer } from "openclaw/plugin-sdk/channel-pairing";
|
|
35
37
|
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
|
36
|
-
import { readChannelAllowFromStore, resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute, upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
|
|
38
|
+
import { ensureConfiguredBindingRouteReady, readChannelAllowFromStore, resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute, upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
|
|
37
39
|
import { channelReadyPatch } from "openclaw/plugin-sdk/gateway-runtime";
|
|
38
40
|
import { redactIdentifier } from "openclaw/plugin-sdk/logging-core";
|
|
39
41
|
import { DEFAULT_GROUP_HISTORY_LIMIT, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
|
|
@@ -55,8 +57,6 @@ import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
|
|
|
55
57
|
//#region extensions/imessage/src/approval-reaction-poller.ts
|
|
56
58
|
const RECENT_CHAT_LIMIT = 50;
|
|
57
59
|
const PER_CHAT_HISTORY_LIMIT = 30;
|
|
58
|
-
const OBSERVED_APPROVAL_PROMPT_TARGET_TTL_MS = 300 * 1e3;
|
|
59
|
-
const accountIdsWithCompletedNoTargetDiscovery = /* @__PURE__ */ new Set();
|
|
60
60
|
function normalizeChatId(value) {
|
|
61
61
|
return asPositiveFiniteNumber(value) ?? null;
|
|
62
62
|
}
|
|
@@ -150,42 +150,13 @@ function bindObservedConversation(params) {
|
|
|
150
150
|
ttlMs
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
|
-
function bindObservedApprovalPrompt(params) {
|
|
154
|
-
if (params.message.is_from_me !== true) return null;
|
|
155
|
-
const messageId = params.message.guid?.trim();
|
|
156
|
-
if (!messageId) return null;
|
|
157
|
-
const binding = extractIMessageApprovalPromptBinding(params.message.text ?? "");
|
|
158
|
-
if (!binding) return null;
|
|
159
|
-
const conversation = buildConversationKeyFromMessage(params.message);
|
|
160
|
-
const expiresAtMs = resolveExpiresAtMsFromDurationMs(OBSERVED_APPROVAL_PROMPT_TARGET_TTL_MS);
|
|
161
|
-
if (expiresAtMs === void 0) return null;
|
|
162
|
-
const target = {
|
|
163
|
-
accountId: params.accountId,
|
|
164
|
-
conversation,
|
|
165
|
-
messageId,
|
|
166
|
-
approvalId: binding.approvalId,
|
|
167
|
-
approvalKind: binding.approvalKind,
|
|
168
|
-
allowedDecisions: binding.allowedDecisions,
|
|
169
|
-
expiresAtMs
|
|
170
|
-
};
|
|
171
|
-
bindObservedConversation({
|
|
172
|
-
target,
|
|
173
|
-
message: params.message
|
|
174
|
-
});
|
|
175
|
-
return target;
|
|
176
|
-
}
|
|
177
153
|
async function pollPendingIMessageApprovalReactions(params) {
|
|
178
|
-
const targets = listPendingIMessageApprovalReactionPollTargets({ accountId: params.accountId });
|
|
179
|
-
|
|
180
|
-
if (targets.length === 0 && !shouldAttemptNoTargetDiscovery) return;
|
|
154
|
+
const targets = await listPendingIMessageApprovalReactionPollTargets({ accountId: params.accountId });
|
|
155
|
+
if (targets.length === 0) return;
|
|
181
156
|
const pendingByMessageId = buildPendingTargetsByMessageId(targets);
|
|
182
157
|
const explicitChatIds = listTargetChatIds(targets);
|
|
183
|
-
const chatIds = params.allowRecentChatDiscovery === true &&
|
|
184
|
-
if (chatIds.length === 0)
|
|
185
|
-
if (shouldAttemptNoTargetDiscovery) accountIdsWithCompletedNoTargetDiscovery.add(params.accountId);
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
let hadHistoryFetchError = false;
|
|
158
|
+
const chatIds = params.allowRecentChatDiscovery === true && targets.length > 0 && hasUnscopedTarget(targets) ? uniqueChatIds([...explicitChatIds, ...await listRecentChatIds(params.client)]) : explicitChatIds;
|
|
159
|
+
if (chatIds.length === 0) return;
|
|
189
160
|
for (const chatId of chatIds) {
|
|
190
161
|
let messages;
|
|
191
162
|
try {
|
|
@@ -194,17 +165,13 @@ async function pollPendingIMessageApprovalReactions(params) {
|
|
|
194
165
|
chatId
|
|
195
166
|
});
|
|
196
167
|
} catch (err) {
|
|
197
|
-
hadHistoryFetchError = true;
|
|
198
168
|
params.logVerboseMessage?.(`imessage: approval reaction poll skipped chat_id=${chatId}: ${String(err)}`);
|
|
199
169
|
continue;
|
|
200
170
|
}
|
|
201
171
|
for (const message of messages) {
|
|
202
172
|
const targetGuid = message.guid?.trim();
|
|
203
173
|
if (!targetGuid) continue;
|
|
204
|
-
const target = pendingByMessageId.get(targetGuid) ?? pendingByMessageId.get(normalizeMessageGuid(targetGuid))
|
|
205
|
-
accountId: params.accountId,
|
|
206
|
-
message
|
|
207
|
-
});
|
|
174
|
+
const target = pendingByMessageId.get(targetGuid) ?? pendingByMessageId.get(normalizeMessageGuid(targetGuid));
|
|
208
175
|
if (!target) continue;
|
|
209
176
|
bindObservedConversation({
|
|
210
177
|
target,
|
|
@@ -216,22 +183,17 @@ async function pollPendingIMessageApprovalReactions(params) {
|
|
|
216
183
|
reaction
|
|
217
184
|
});
|
|
218
185
|
if (!reactionPayload) continue;
|
|
219
|
-
|
|
186
|
+
if ((await handleIMessageApprovalReaction({
|
|
220
187
|
cfg: params.cfg,
|
|
221
188
|
accountId: params.accountId,
|
|
222
189
|
message: reactionPayload,
|
|
223
190
|
bodyText: reactionPayload.text ?? "",
|
|
224
191
|
gatewayRuntime: params.gatewayRuntime,
|
|
225
192
|
logVerboseMessage: params.logVerboseMessage
|
|
226
|
-
});
|
|
227
|
-
if (handled.stopPolling) {
|
|
228
|
-
if (shouldAttemptNoTargetDiscovery && handled.stopPollingReason !== "resolver-error") break;
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
193
|
+
})).stopPolling) return;
|
|
231
194
|
}
|
|
232
195
|
}
|
|
233
196
|
}
|
|
234
|
-
if (shouldAttemptNoTargetDiscovery && !hadHistoryFetchError) accountIdsWithCompletedNoTargetDiscovery.add(params.accountId);
|
|
235
197
|
}
|
|
236
198
|
//#endregion
|
|
237
199
|
//#region extensions/imessage/src/chat.ts
|
|
@@ -1033,7 +995,7 @@ function isStaleIMessageBacklog(message, nowMs, thresholdMs = IMESSAGE_STALE_INB
|
|
|
1033
995
|
//#endregion
|
|
1034
996
|
//#region extensions/imessage/src/conversation-route.ts
|
|
1035
997
|
function resolveIMessageConversationRoute(params) {
|
|
1036
|
-
|
|
998
|
+
const route = resolveAgentRoute({
|
|
1037
999
|
cfg: params.cfg,
|
|
1038
1000
|
channel: "imessage",
|
|
1039
1001
|
accountId: params.accountId,
|
|
@@ -1047,28 +1009,30 @@ function resolveIMessageConversationRoute(params) {
|
|
|
1047
1009
|
sender: params.sender,
|
|
1048
1010
|
chatId: params.chatId
|
|
1049
1011
|
});
|
|
1050
|
-
if (!conversationId) return
|
|
1051
|
-
|
|
1012
|
+
if (!conversationId) return {
|
|
1013
|
+
route,
|
|
1014
|
+
bindingResolution: null
|
|
1015
|
+
};
|
|
1016
|
+
const conversation = {
|
|
1017
|
+
channel: "imessage",
|
|
1018
|
+
accountId: params.accountId,
|
|
1019
|
+
conversationId
|
|
1020
|
+
};
|
|
1021
|
+
const configuredRoute = resolveConfiguredBindingRoute({
|
|
1052
1022
|
cfg: params.cfg,
|
|
1053
1023
|
route,
|
|
1054
|
-
conversation
|
|
1055
|
-
|
|
1056
|
-
accountId: params.accountId,
|
|
1057
|
-
conversationId
|
|
1058
|
-
}
|
|
1059
|
-
}).route;
|
|
1024
|
+
conversation
|
|
1025
|
+
});
|
|
1060
1026
|
const runtimeRoute = resolveRuntimeConversationBindingRoute({
|
|
1061
|
-
route,
|
|
1062
|
-
conversation
|
|
1063
|
-
channel: "imessage",
|
|
1064
|
-
accountId: params.accountId,
|
|
1065
|
-
conversationId
|
|
1066
|
-
}
|
|
1027
|
+
route: configuredRoute.route,
|
|
1028
|
+
conversation
|
|
1067
1029
|
});
|
|
1068
|
-
route = runtimeRoute.route;
|
|
1069
1030
|
if (runtimeRoute.bindingRecord && !runtimeRoute.boundSessionKey) logVerbose(`imessage: plugin-bound conversation ${conversationId}`);
|
|
1070
1031
|
else if (runtimeRoute.boundSessionKey) logVerbose(`imessage: routed via bound conversation ${conversationId} -> ${runtimeRoute.boundSessionKey}`);
|
|
1071
|
-
return
|
|
1032
|
+
return {
|
|
1033
|
+
route: runtimeRoute.route,
|
|
1034
|
+
bindingResolution: runtimeRoute.bindingRecord ? null : configuredRoute.bindingResolution
|
|
1035
|
+
};
|
|
1072
1036
|
}
|
|
1073
1037
|
//#endregion
|
|
1074
1038
|
//#region extensions/imessage/src/monitor/reflection-guard.ts
|
|
@@ -1391,7 +1355,7 @@ async function resolveIMessageInboundDecision(params) {
|
|
|
1391
1355
|
const groupId = isGroup ? groupIdCandidate : void 0;
|
|
1392
1356
|
const hasControlCommandInMessage = hasControlCommand(messageText, params.cfg);
|
|
1393
1357
|
const groupAllowFromForAccess = isGroup ? groupAllowFromWithLegacyChatTargets : params.groupAllowFrom;
|
|
1394
|
-
const route = resolveIMessageConversationRoute({
|
|
1358
|
+
const { route, bindingResolution } = resolveIMessageConversationRoute({
|
|
1395
1359
|
cfg: params.cfg,
|
|
1396
1360
|
accountId: params.accountId,
|
|
1397
1361
|
isGroup,
|
|
@@ -1689,6 +1653,7 @@ async function resolveIMessageInboundDecision(params) {
|
|
|
1689
1653
|
sender,
|
|
1690
1654
|
senderNormalized,
|
|
1691
1655
|
route,
|
|
1656
|
+
bindingResolution,
|
|
1692
1657
|
bodyText,
|
|
1693
1658
|
createdAt,
|
|
1694
1659
|
replyContext: filteredReplyContext,
|
|
@@ -1754,11 +1719,8 @@ async function buildIMessageInboundContext(params) {
|
|
|
1754
1719
|
envelope: envelopeOptions
|
|
1755
1720
|
})
|
|
1756
1721
|
});
|
|
1757
|
-
const
|
|
1758
|
-
|
|
1759
|
-
accountId: decision.route.accountId,
|
|
1760
|
-
sender: decision.sender
|
|
1761
|
-
});
|
|
1722
|
+
const directService = resolveIMessageDirectChatService(params.accountService, decision.chatGuid) ?? "auto";
|
|
1723
|
+
const imessageTo = decision.isGroup ? chatTarget || `imessage:${decision.sender}` : `${directService}:${decision.sender}`;
|
|
1762
1724
|
const imessageFrom = decision.isGroup ? `imessage:group:${chatId ?? "unknown"}` : imessageTo;
|
|
1763
1725
|
const inboundHistory = !decision.isGroup && params.dmHistory?.inboundHistory ? params.dmHistory.inboundHistory : decision.isGroup && decision.historyKey && params.historyLimit > 0 ? createChannelHistoryWindow({ historyMap: params.groupHistories }).buildInboundHistory({
|
|
1764
1726
|
historyKey: decision.historyKey,
|
|
@@ -1792,6 +1754,10 @@ async function buildIMessageInboundContext(params) {
|
|
|
1792
1754
|
conversation: {
|
|
1793
1755
|
kind: decision.isGroup ? "group" : "direct",
|
|
1794
1756
|
id: chatId != null ? String(chatId) : decision.sender,
|
|
1757
|
+
...decision.isGroup && chatId == null ? {} : { routePeer: {
|
|
1758
|
+
kind: decision.isGroup ? "group" : "direct",
|
|
1759
|
+
id: decision.isGroup ? String(chatId) : decision.senderNormalized
|
|
1760
|
+
} },
|
|
1795
1761
|
label: fromLabel
|
|
1796
1762
|
},
|
|
1797
1763
|
route: {
|
|
@@ -1840,13 +1806,6 @@ function buildIMessageEchoScope(params) {
|
|
|
1840
1806
|
if (params.chatIdentifier) scopes.push(`${params.accountId}:chat_identifier:${params.chatIdentifier}`);
|
|
1841
1807
|
return scopes;
|
|
1842
1808
|
}
|
|
1843
|
-
function buildDirectIMessageReplyTarget(params) {
|
|
1844
|
-
if (resolveIMessageAccount({
|
|
1845
|
-
cfg: params.cfg,
|
|
1846
|
-
accountId: params.accountId
|
|
1847
|
-
}).config.service === "sms") return `sms:${params.sender}`;
|
|
1848
|
-
return `imessage:${params.sender}`;
|
|
1849
|
-
}
|
|
1850
1809
|
function describeIMessageEchoDropLog(params) {
|
|
1851
1810
|
const preview = truncateUtf16Safe(params.messageText, 50);
|
|
1852
1811
|
return `imessage: skipping echo message${params.messageId ? ` id=${params.messageId}` : ""}: "${preview}"`;
|
|
@@ -2956,6 +2915,16 @@ async function monitorIMessageProvider(opts = {}) {
|
|
|
2956
2915
|
});
|
|
2957
2916
|
return;
|
|
2958
2917
|
}
|
|
2918
|
+
if (decision.bindingResolution) {
|
|
2919
|
+
const readiness = await ensureConfiguredBindingRouteReady({
|
|
2920
|
+
cfg,
|
|
2921
|
+
bindingResolution: decision.bindingResolution
|
|
2922
|
+
});
|
|
2923
|
+
if (!readiness.ok) {
|
|
2924
|
+
runtime.error?.(`imessage: dropped inbound message; configured ACP binding unavailable for ${decision.bindingResolution.record.conversation.conversationId}: ${readiness.error}`);
|
|
2925
|
+
return;
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2959
2928
|
const storePath = resolveStorePath(cfg.session?.store, { agentId: decision.route.agentId });
|
|
2960
2929
|
const privateApiStatus = getCachedIMessagePrivateApiStatus(cliPath);
|
|
2961
2930
|
const supportsTyping = imessageRpcSupportsMethod(privateApiStatus, "typing");
|
|
@@ -2975,11 +2944,9 @@ async function monitorIMessageProvider(opts = {}) {
|
|
|
2975
2944
|
chatType: decision.isGroup ? "group" : "direct"
|
|
2976
2945
|
});
|
|
2977
2946
|
const shouldUseDirectToolTypingOptions = !decision.isGroup && sendPolicy !== "deny" && (configuredTypingMode === void 0 || configuredTypingMode === "instant");
|
|
2978
|
-
const
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
sender: decision.sender
|
|
2982
|
-
}) : void 0;
|
|
2947
|
+
const shouldStartDirectTyping = supportsTyping && shouldUseDirectToolTypingOptions;
|
|
2948
|
+
const earlyDirectTypingService = resolveIMessageDirectChatService(imessageCfg.service, decision.chatGuid) ?? "auto";
|
|
2949
|
+
const earlyDirectTypingTarget = shouldStartDirectTyping ? `${earlyDirectTypingService}:${decision.sender}` : void 0;
|
|
2983
2950
|
let stopEarlyDirectTyping;
|
|
2984
2951
|
if (earlyDirectTypingTarget) {
|
|
2985
2952
|
const earlyDirectTypingStarted = sendIMessageTyping(earlyDirectTypingTarget, true, {
|
|
@@ -3056,8 +3023,10 @@ async function monitorIMessageProvider(opts = {}) {
|
|
|
3056
3023
|
envelopeOptions: resolveEnvelopeFormatOptions(cfg),
|
|
3057
3024
|
logVerbose
|
|
3058
3025
|
}) : void 0;
|
|
3026
|
+
const pluginChannelRuntime = opts.channelRuntime;
|
|
3059
3027
|
const { ctxPayload, chatTarget, imessageTo } = await buildIMessageInboundContext({
|
|
3060
3028
|
cfg,
|
|
3029
|
+
accountService: imessageCfg.service,
|
|
3061
3030
|
decision: contextDecision,
|
|
3062
3031
|
message,
|
|
3063
3032
|
previousTimestamp,
|
|
@@ -3065,7 +3034,7 @@ async function monitorIMessageProvider(opts = {}) {
|
|
|
3065
3034
|
historyLimit,
|
|
3066
3035
|
groupHistories,
|
|
3067
3036
|
dmHistory,
|
|
3068
|
-
buildContext:
|
|
3037
|
+
buildContext: pluginChannelRuntime?.inbound.buildContext,
|
|
3069
3038
|
media: { facts: mediaAttachments }
|
|
3070
3039
|
});
|
|
3071
3040
|
const updateTarget = chatTarget || imessageTo;
|
|
@@ -3080,7 +3049,8 @@ async function monitorIMessageProvider(opts = {}) {
|
|
|
3080
3049
|
}
|
|
3081
3050
|
const sendReadReceipts = imessageCfg.sendReadReceipts !== false;
|
|
3082
3051
|
const typingTarget = ctxPayload.To;
|
|
3083
|
-
|
|
3052
|
+
const readTarget = !decision.isGroup && decision.chatGuid ? `chat_guid:${decision.chatGuid}` : typingTarget;
|
|
3053
|
+
if (supportsRead && sendReadReceipts && readTarget) markIMessageChatRead(readTarget, {
|
|
3084
3054
|
cfg,
|
|
3085
3055
|
accountId: accountInfo.accountId,
|
|
3086
3056
|
cliPath,
|
|
@@ -3217,6 +3187,7 @@ async function monitorIMessageProvider(opts = {}) {
|
|
|
3217
3187
|
sessionKey: decision.route.sessionKey
|
|
3218
3188
|
},
|
|
3219
3189
|
ctxPayload,
|
|
3190
|
+
dispatchReplyFromConfig: pluginChannelRuntime?.reply?.dispatchReplyFromConfig,
|
|
3220
3191
|
record: {
|
|
3221
3192
|
updateLastRoute: !decision.isGroup && updateTarget ? {
|
|
3222
3193
|
sessionKey: inboundLastRouteSessionKey,
|
|
@@ -21,6 +21,11 @@ function parseDirectChatIdentity(raw) {
|
|
|
21
21
|
if (parts.length !== 1) return;
|
|
22
22
|
if (trimmed.startsWith("+") || EMAIL_HANDLE_PATTERN.test(trimmed)) return { identifier: trimmed.toLowerCase() };
|
|
23
23
|
}
|
|
24
|
+
function resolveIMessageDirectChatService(configuredService, chatGuid) {
|
|
25
|
+
if (configuredService === "imessage" || configuredService === "sms") return configuredService;
|
|
26
|
+
const observedService = chatGuid ? parseDirectChatIdentity(chatGuid)?.service : void 0;
|
|
27
|
+
return observedService === "imessage" || observedService === "sms" ? observedService : void 0;
|
|
28
|
+
}
|
|
24
29
|
function isIMessageEmailChatIdentifier(raw) {
|
|
25
30
|
const identity = parseDirectChatIdentity(raw);
|
|
26
31
|
return Boolean(identity && EMAIL_HANDLE_PATTERN.test(identity.identifier));
|
|
@@ -345,4 +350,4 @@ function isIMessageCurrentMessageInChat(params) {
|
|
|
345
350
|
}) === "match";
|
|
346
351
|
}
|
|
347
352
|
//#endregion
|
|
348
|
-
export { normalizeDirectChatIdentifier as _, findLatestIMessageEntryForChat as a, rememberIMessageReplyCache as c, resolveIMessageReplyCacheEntryKey as d, getIMessageRuntime as f, isIMessageEmailChatIdentifier as g, chatContextFromIMessageTarget as h, IMESSAGE_REPLY_CACHE_NAMESPACE as i, resolveIMessageCachedResourceBinding as l, setIMessageRuntime as m, IMESSAGE_REPLY_CACHE_COUNTER_NAMESPACE as n, isIMessageCurrentMessageInChat as o, getOptionalIMessageRuntime as p, IMESSAGE_REPLY_CACHE_MAX_ENTRIES as r, isKnownFromMeIMessageMessageId as s, IMESSAGE_REPLY_CACHE_COUNTER_KEY as t, resolveIMessageMessageId as u };
|
|
353
|
+
export { normalizeDirectChatIdentifier as _, findLatestIMessageEntryForChat as a, rememberIMessageReplyCache as c, resolveIMessageReplyCacheEntryKey as d, getIMessageRuntime as f, isIMessageEmailChatIdentifier as g, chatContextFromIMessageTarget as h, IMESSAGE_REPLY_CACHE_NAMESPACE as i, resolveIMessageCachedResourceBinding as l, setIMessageRuntime as m, IMESSAGE_REPLY_CACHE_COUNTER_NAMESPACE as n, isIMessageCurrentMessageInChat as o, getOptionalIMessageRuntime as p, IMESSAGE_REPLY_CACHE_MAX_ENTRIES as r, isKnownFromMeIMessageMessageId as s, IMESSAGE_REPLY_CACHE_COUNTER_KEY as t, resolveIMessageMessageId as u, resolveIMessageDirectChatService as v };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as getIMessageRuntime } from "./monitor-reply-cache-
|
|
1
|
+
import { f as getIMessageRuntime } from "./monitor-reply-cache-BdeUQaHO.js";
|
|
2
2
|
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
//#region extensions/imessage/src/monitor/echo-text-corruption.ts
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
|
|
2
|
+
import { t as resolveIMessageReactionContext } from "./reaction-context-DaNrZqYo.js";
|
|
2
3
|
import { createQuestionReactionTargetStore, questionGatewayRuntime } from "openclaw/plugin-sdk/question-gateway-runtime";
|
|
3
4
|
//#region extensions/imessage/src/question-reactions.ts
|
|
4
5
|
var question_reactions_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
//#region extensions/imessage/src/monitor/reaction-context.ts
|
|
2
|
+
const TAPBACK_TEXT_PATTERNS = [
|
|
3
|
+
{
|
|
4
|
+
prefix: "loved",
|
|
5
|
+
action: "added",
|
|
6
|
+
emoji: "❤️"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
prefix: "liked",
|
|
10
|
+
action: "added",
|
|
11
|
+
emoji: "👍"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
prefix: "disliked",
|
|
15
|
+
action: "added",
|
|
16
|
+
emoji: "👎"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
prefix: "laughed at",
|
|
20
|
+
action: "added",
|
|
21
|
+
emoji: "😂"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
prefix: "emphasized",
|
|
25
|
+
action: "added",
|
|
26
|
+
emoji: "‼️"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
prefix: "questioned",
|
|
30
|
+
action: "added",
|
|
31
|
+
emoji: "❓"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
prefix: "removed a heart from",
|
|
35
|
+
action: "removed",
|
|
36
|
+
emoji: "❤️"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
prefix: "removed a like from",
|
|
40
|
+
action: "removed",
|
|
41
|
+
emoji: "👍"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
prefix: "removed a dislike from",
|
|
45
|
+
action: "removed",
|
|
46
|
+
emoji: "👎"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
prefix: "removed a laugh from",
|
|
50
|
+
action: "removed",
|
|
51
|
+
emoji: "😂"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
prefix: "removed an emphasis from",
|
|
55
|
+
action: "removed",
|
|
56
|
+
emoji: "‼️"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
prefix: "removed a question from",
|
|
60
|
+
action: "removed",
|
|
61
|
+
emoji: "❓"
|
|
62
|
+
}
|
|
63
|
+
];
|
|
64
|
+
function normalizeReactionValue(value) {
|
|
65
|
+
return typeof value === "string" ? value.trim().replace(/^p:\d+\//iu, "") || void 0 : void 0;
|
|
66
|
+
}
|
|
67
|
+
function resolveReactionTargetGuidCandidates(...values) {
|
|
68
|
+
const candidates = [];
|
|
69
|
+
for (const value of values) {
|
|
70
|
+
if (typeof value !== "string") continue;
|
|
71
|
+
const raw = value.trim();
|
|
72
|
+
if (!raw) continue;
|
|
73
|
+
const normalized = raw.replace(/^p:\d+\//iu, "");
|
|
74
|
+
for (const candidate of [normalized, raw]) if (candidate && !candidates.includes(candidate)) candidates.push(candidate);
|
|
75
|
+
}
|
|
76
|
+
return candidates;
|
|
77
|
+
}
|
|
78
|
+
function resolveTapbackTextContext(bodyText) {
|
|
79
|
+
const lower = bodyText.toLowerCase();
|
|
80
|
+
for (const pattern of TAPBACK_TEXT_PATTERNS) {
|
|
81
|
+
if (!lower.startsWith(pattern.prefix)) continue;
|
|
82
|
+
const afterPrefix = bodyText.slice(pattern.prefix.length).trim();
|
|
83
|
+
if (!/^["“]/u.test(afterPrefix)) continue;
|
|
84
|
+
return {
|
|
85
|
+
action: pattern.action,
|
|
86
|
+
emoji: pattern.emoji,
|
|
87
|
+
targetText: afterPrefix.replace(/^["“]/u, "").replace(/["”]$/u, "").trim()
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
function resolveIMessageReactionContext(message, bodyText) {
|
|
93
|
+
if (message.is_reaction === true || message.is_tapback === true || typeof message.associated_message_type === "number" && Number.isFinite(message.associated_message_type) && message.associated_message_type >= 2e3 && message.associated_message_type < 4e3) {
|
|
94
|
+
const targetGuids = resolveReactionTargetGuidCandidates(message.reacted_to_guid, message.associated_message_guid);
|
|
95
|
+
return {
|
|
96
|
+
action: message.is_reaction_add === false ? "removed" : "added",
|
|
97
|
+
emoji: normalizeReactionValue(message.reaction_emoji) ?? normalizeReactionValue(message.reaction_type) ?? "reaction",
|
|
98
|
+
targetGuid: targetGuids[0],
|
|
99
|
+
targetGuids
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return resolveTapbackTextContext(bodyText);
|
|
103
|
+
}
|
|
104
|
+
//#endregion
|
|
105
|
+
export { resolveIMessageReactionContext as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { p as resolveLocalIMessageChatDbPath, u as expandIMessageUserPath } from "./accounts-D00Njxg2.js";
|
|
2
|
-
import { g as isIMessageEmailChatIdentifier, h as chatContextFromIMessageTarget, l as resolveIMessageCachedResourceBinding, u as resolveIMessageMessageId } from "./monitor-reply-cache-
|
|
2
|
+
import { g as isIMessageEmailChatIdentifier, h as chatContextFromIMessageTarget, l as resolveIMessageCachedResourceBinding, u as resolveIMessageMessageId } from "./monitor-reply-cache-BdeUQaHO.js";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { normalizeScpRemoteHost } from "openclaw/plugin-sdk/host-runtime";
|
|
5
5
|
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
|
@@ -121,7 +121,11 @@ function checkIMessageResourceBinding(params) {
|
|
|
121
121
|
FROM message m
|
|
122
122
|
JOIN chat_message_join cmj ON cmj.message_id = m.ROWID
|
|
123
123
|
JOIN chat c ON c.ROWID = cmj.chat_id
|
|
124
|
-
WHERE m.guid = ?`).all(messageGuid).
|
|
124
|
+
WHERE m.guid = ?`).all(messageGuid).map((row) => ({
|
|
125
|
+
chatId: row.chatId,
|
|
126
|
+
chatGuid: row.chatGuid,
|
|
127
|
+
chatIdentifier: row.chatIdentifier
|
|
128
|
+
})).some((row) => (!hasChatId || row.chatId === chatId) && (expectedChatGuids.length === 0 || matchesAnyChatCandidate(row.chatGuid, expectedChatGuids)) && (expectedChatIdentifiers.length === 0 || matchesAnyChatCandidate(row.chatIdentifier, expectedChatIdentifiers)) && (identifierChatGuids.length === 0 || matchesAnyChatCandidate(row.chatGuid, identifierChatGuids))) ? "match" : "mismatch";
|
|
125
129
|
} catch {
|
|
126
130
|
return "unavailable";
|
|
127
131
|
} finally {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { __exportAll as t };
|
package/dist/runtime-api.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { F as imessageMessageActions, I as probeIMessage, h as normalizeIMessageMessagingTarget, l as chunkTextForOutbound, m as looksLikeIMessageTargetId, n as resolveIMessageGroupToolPolicy, t as resolveIMessageGroupRequireMention } from "./group-policy-DF9xSdik.js";
|
|
2
1
|
import { o as resolveIMessageAccount } from "./accounts-D00Njxg2.js";
|
|
3
|
-
import { m as setIMessageRuntime } from "./monitor-reply-cache-
|
|
2
|
+
import { m as setIMessageRuntime } from "./monitor-reply-cache-BdeUQaHO.js";
|
|
3
|
+
import { h as normalizeIMessageMessagingTarget, l as chunkTextForOutbound, m as looksLikeIMessageTargetId, n as resolveIMessageGroupToolPolicy, t as resolveIMessageGroupRequireMention, v as imessageMessageActions, y as probeIMessage } from "./group-policy-Ca3c5KES.js";
|
|
4
4
|
import { n as IMessageConfigSchema } from "./config-schema-DV0KP5nC.js";
|
|
5
|
-
import { t as sendMessageIMessage } from "./send-
|
|
6
|
-
import { t as monitorIMessageProvider } from "./monitor-
|
|
5
|
+
import { t as sendMessageIMessage } from "./send-Dake4Awx.js";
|
|
6
|
+
import { t as monitorIMessageProvider } from "./monitor-Uv5RaRTk.js";
|
|
7
7
|
import { buildComputedAccountStatusSnapshot, collectStatusIssuesFromLastError } from "openclaw/plugin-sdk/status-helpers";
|
|
8
8
|
import { formatTrimmedAllowFromEntries } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
9
9
|
import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
|
|
@@ -445,7 +445,7 @@ const FINAL_PRIVATE_MARKER_RE = /(?:#\+){2,}#?|\bassistant\s+to\s*=\s*\w+|^[ \t]
|
|
|
445
445
|
const PRIVATE_USE_START = 57344;
|
|
446
446
|
const PRIVATE_USE_END = 63743;
|
|
447
447
|
const MAX_PRIVATE_MARKDOWN_UNWRAP_PASSES = 32;
|
|
448
|
-
const PLAIN_TEXT_HTML_TAG_RE = /<\/?[a-z][a-z0-9_
|
|
448
|
+
const PLAIN_TEXT_HTML_TAG_RE = /<\/?[a-z][a-z0-9_.:-]*(?=[\s/>])[^>]*>/gi;
|
|
449
449
|
const PRIVATE_PROVIDER_TAG_NAMES = [
|
|
450
450
|
"think",
|
|
451
451
|
"thinking",
|