




















@@ -5,12 +5,10 @@ import {
55import { createLazyChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-adapter-runtime";
66import type { ChannelApprovalNativeRuntimeAdapter } from "openclaw/plugin-sdk/approval-handler-runtime";
77import {
8-createChannelApprovalForwardingEvaluator,
98createChannelApproverDmTargetResolver,
109createChannelNativeOriginTargetResolver,
10+createNativeApprovalChannelRouteGates,
1111createNativeApprovalForwardingFallbackSuppressor,
12-nativeApprovalTargetsMatch,
13-resolveApprovalRequestSessionTarget,
1412shouldSuppressLocalNativeExecApprovalPrompt,
1513} from "openclaw/plugin-sdk/approval-native-runtime";
1614import {
@@ -48,8 +46,8 @@ import { normalizeIMessageMessagingTarget } from "./normalize.js";
4846import { inferIMessageTargetChatType } from "./targets.js";
49475048type ApprovalRequest = ExecApprovalRequest | PluginApprovalRequest;
51-type ApprovalKind = "exec" | "plugin";
5249type ApprovalForwardingConfig = NonNullable<NonNullable<OpenClawConfig["approvals"]>["exec"]>;
50+type ApprovalForwardingMode = NonNullable<ApprovalForwardingConfig["mode"]>;
5351type ChannelApprovalForwardTarget = Parameters<
5452NonNullable<
5553NonNullable<ChannelApprovalCapability["delivery"]>["shouldSuppressForwardingFallback"]
@@ -61,6 +59,7 @@ type IMessageApprovalTarget = {
6159threadId?: string | number | null;
6260};
636162+const DEFAULT_APPROVAL_FORWARDING_MODE: ApprovalForwardingMode = "session";
6463const DEFAULT_PLUGIN_APPROVAL_DECISIONS: readonly ExecApprovalReplyDecision[] = [
6564"allow-once",
6665"allow-always",
@@ -74,35 +73,6 @@ function isIMessageApprovalTransportEnabled(params: {
7473return resolveIMessageAccount({ cfg: params.cfg, accountId: params.accountId }).enabled;
7574}
767577-function targetAccountMatchesIMessageAccount(params: {
78-cfg: OpenClawConfig;
79-targetAccountId?: string | null;
80-accountId?: string | null;
81-}): boolean {
82-const targetAccountId = normalizeOptionalString(params.targetAccountId);
83-const accountId = normalizeOptionalString(params.accountId);
84-if (targetAccountId) {
85-return !accountId || normalizeAccountId(targetAccountId) === normalizeAccountId(accountId);
86-}
87-if (!accountId) {
88-return true;
89-}
90-const normalizedAccountId = normalizeAccountId(accountId);
91-const defaultAccountId = normalizeAccountId(resolveDefaultIMessageAccountId(params.cfg));
92-if (normalizedAccountId === defaultAccountId) {
93-return true;
94-}
95-const enabledAccountIds = listIMessageAccountIds(params.cfg)
96-.filter((candidateAccountId) =>
97-isIMessageApprovalTransportEnabled({
98-cfg: params.cfg,
99-accountId: candidateAccountId,
100-}),
101-)
102-.map((candidateAccountId) => normalizeAccountId(candidateAccountId));
103-return enabledAccountIds.length === 1 && enabledAccountIds[0] === normalizedAccountId;
104-}
105-10676function normalizeIMessageForwardTarget(
10777target: Pick<ChannelApprovalForwardTarget, "channel" | "to" | "accountId" | "threadId">,
10878): IMessageApprovalTarget | null {
@@ -120,73 +90,6 @@ function normalizeIMessageForwardTarget(
12090};
12191}
12292123-function hasMatchingIMessageTarget(params: {
124-cfg: OpenClawConfig;
125-config: ApprovalForwardingConfig;
126-accountId?: string | null;
127-target?: ChannelApprovalForwardTarget;
128-}): boolean {
129-const candidateTarget = params.target ? normalizeIMessageForwardTarget(params.target) : null;
130-return (params.config.targets ?? []).some((target) => {
131-const configuredTarget = normalizeIMessageForwardTarget(target);
132-if (!configuredTarget) {
133-return false;
134-}
135-if (
136-!targetAccountMatchesIMessageAccount({
137-cfg: params.cfg,
138-targetAccountId: configuredTarget.accountId,
139-accountId: params.accountId,
140-})
141-) {
142-return false;
143-}
144-if (!candidateTarget) {
145-return true;
146-}
147-return nativeApprovalTargetsMatch({
148-channel: "imessage",
149-left: configuredTarget,
150-right: candidateTarget,
151-});
152-});
153-}
154-155-function hasIMessageOriginOrSessionTarget(params: {
156-cfg: OpenClawConfig;
157-accountId?: string | null;
158-request: ApprovalRequest;
159-}): boolean {
160-if (resolveTurnSourceIMessageOriginTarget(params.request)) {
161-return true;
162-}
163-164-const sessionTarget = resolveApprovalRequestSessionTarget({
165-cfg: params.cfg,
166-request: params.request,
167-});
168-return (
169-normalizeLowercaseStringOrEmpty(sessionTarget?.channel) === "imessage" &&
170-targetAccountMatchesIMessageAccount({
171-cfg: params.cfg,
172-targetAccountId: sessionTarget?.accountId,
173-accountId: params.accountId,
174-})
175-);
176-}
177-178-const imessageApprovalForwarding = createChannelApprovalForwardingEvaluator({
179-channel: "imessage",
180-isTransportEnabled: isIMessageApprovalTransportEnabled,
181-hasMatchingTarget: hasMatchingIMessageTarget,
182-hasOriginOrSessionTarget: hasIMessageOriginOrSessionTarget,
183-});
184-185-const canApprovalPotentiallyRouteToIMessage = imessageApprovalForwarding.isPotentialRoute;
186-const canAnyApprovalPotentiallyRouteToIMessage = imessageApprovalForwarding.canAnyPotentiallyRoute;
187-const isIMessageSessionApprovalEligible = imessageApprovalForwarding.isSessionEligible;
188-const isIMessageExplicitTargetEligible = imessageApprovalForwarding.isExplicitTargetEligible;
189-19093function resolveTurnSourceIMessageOriginTarget(
19194request: ApprovalRequest,
19295): IMessageApprovalTarget | null {
@@ -212,6 +115,24 @@ function resolveSessionIMessageOriginTarget(sessionTarget: {
212115return to ? { to, accountId: normalizeOptionalString(sessionTarget.accountId) } : null;
213116}
214117118+const imessageApprovalRouteGates = createNativeApprovalChannelRouteGates({
119+channel: "imessage",
120+defaultForwardingMode: DEFAULT_APPROVAL_FORWARDING_MODE,
121+isTransportEnabled: isIMessageApprovalTransportEnabled,
122+listAccountIds: listIMessageAccountIds,
123+resolveDefaultAccountId: resolveDefaultIMessageAccountId,
124+normalizeForwardTarget: normalizeIMessageForwardTarget,
125+resolveTurnSourceTarget: resolveTurnSourceIMessageOriginTarget,
126+});
127+128+const {
129+canApprovalPotentiallyRouteToChannel: canApprovalPotentiallyRouteToIMessage,
130+canAnyApprovalPotentiallyRouteToChannel: canAnyApprovalPotentiallyRouteToIMessage,
131+isSessionApprovalEligible: isIMessageSessionApprovalEligible,
132+isExplicitTargetEligible: isIMessageExplicitTargetEligible,
133+shouldHandleApprovalRequest: shouldHandleIMessageApprovalRequest,
134+} = imessageApprovalRouteGates;
135+215136function resolveIMessageSessionTargetFromSessionKey(
216137sessionKey?: string | null,
217138): IMessageApprovalTarget | null {
@@ -308,15 +229,6 @@ export function shouldSuppressLocalIMessageExecApprovalPrompt(params: {
308229});
309230}
310231311-function shouldHandleIMessageApprovalRequest(params: {
312-cfg: OpenClawConfig;
313-accountId?: string | null;
314-approvalKind?: ApprovalKind;
315-request: ApprovalRequest;
316-}): boolean {
317-return imessageApprovalForwarding.shouldHandleRequest(params);
318-}
319-320232const resolveIMessageOriginTargetBase = createChannelNativeOriginTargetResolver({
321233channel: "imessage",
322234shouldHandleRequest: shouldHandleIMessageApprovalRequest,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。