@openclaw/msteams 2026.7.2-beta.7 → 2026.8.1-beta.2

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.
@@ -1,6 +1,6 @@
1
1
  require("./runtime-api.cjs");
2
- const require_resolve_allowlist = require("./resolve-allowlist-CEj9sABO.cjs");
3
- const require_setup_surface = require("./setup-surface-ByWjaXEn.cjs");
2
+ const require_resolve_allowlist = require("./resolve-allowlist-C6YcNC9a.cjs");
3
+ const require_setup_surface = require("./setup-surface-DAhGL2h8.cjs");
4
4
  const require_config_schema = require("./config-schema-C4CszdDi.cjs");
5
5
  let openclaw_plugin_sdk_account_helpers = require("openclaw/plugin-sdk/account-helpers");
6
6
  let openclaw_plugin_sdk_channel_core = require("openclaw/plugin-sdk/channel-core");
@@ -13,6 +13,7 @@ let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime
13
13
  let openclaw_plugin_sdk_status_helpers = require("openclaw/plugin-sdk/status-helpers");
14
14
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
15
15
  let typebox = require("typebox");
16
+ let openclaw_plugin_sdk_reply_reference = require("openclaw/plugin-sdk/reply-reference");
16
17
  let openclaw_plugin_sdk_approval_auth_runtime = require("openclaw/plugin-sdk/approval-auth-runtime");
17
18
  let openclaw_plugin_sdk_channel_actions = require("openclaw/plugin-sdk/channel-actions");
18
19
  let openclaw_plugin_sdk_routing = require("openclaw/plugin-sdk/routing");
@@ -23,46 +24,6 @@ let openclaw_plugin_sdk_runtime_group_policy = require("openclaw/plugin-sdk/runt
23
24
  let openclaw_plugin_sdk_text_chunking = require("openclaw/plugin-sdk/text-chunking");
24
25
  let openclaw_plugin_sdk_channel_status = require("openclaw/plugin-sdk/channel-status");
25
26
  let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
26
- //#region extensions/msteams/src/approval-auth.ts
27
- const MSTEAMS_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
28
- function normalizeMSTeamsApproverId(value) {
29
- const normalized = require_resolve_allowlist.normalizeMSTeamsMessagingTarget(String(value));
30
- if (!normalized?.startsWith("user:")) return;
31
- const id = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(normalized.slice(5));
32
- if (!id) return;
33
- return MSTEAMS_ID_RE.test(id) ? id : void 0;
34
- }
35
- function resolveMSTeamsChannelConfig(cfg) {
36
- return cfg.channels?.msteams;
37
- }
38
- const msTeamsApprovalAuth = (0, openclaw_plugin_sdk_approval_auth_runtime.createChannelApprovalAuth)({
39
- channelLabel: "Microsoft Teams",
40
- resolveInputs: ({ cfg }) => {
41
- const channel = resolveMSTeamsChannelConfig(cfg);
42
- return {
43
- allowFrom: channel?.allowFrom,
44
- defaultTo: channel?.defaultTo
45
- };
46
- },
47
- normalizeApprover: normalizeMSTeamsApproverId,
48
- normalizeSenderId: (value) => {
49
- const trimmed = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(value);
50
- if (!trimmed) return;
51
- return MSTEAMS_ID_RE.test(trimmed) ? trimmed : void 0;
52
- }
53
- }).approvalAuth;
54
- //#endregion
55
- //#region extensions/msteams/src/doctor.ts
56
- const isMSTeamsMutableAllowEntry = (0, openclaw_plugin_sdk_channel_policy.buildMutableAllowEntryDetector)({
57
- prefixes: ["msteams:", "user:"],
58
- stableIdPattern: /^[^\s@]+$/
59
- });
60
- const collectMSTeamsMutableAllowlistWarnings = (0, openclaw_plugin_sdk_channel_policy.createDangerousNameMatchingMutableAllowlistWarningCollector)({
61
- channel: "msteams",
62
- detector: isMSTeamsMutableAllowEntry,
63
- collectLists: (scope) => (0, openclaw_plugin_sdk_channel_policy.collectStandardAllowlistLists)(scope)
64
- });
65
- //#endregion
66
27
  //#region extensions/msteams/src/policy.ts
67
28
  const teamScopeKey = (teamKey) => (0, openclaw_plugin_sdk_channel_policy.scopeKey)(["team", teamKey]);
68
29
  const channelScopeKey = (teamKey, channelKey) => (0, openclaw_plugin_sdk_channel_policy.scopeKey)(["team", teamKey], ["channel", channelKey]);
@@ -218,6 +179,115 @@ function resolveMSTeamsReplyPolicy(params) {
218
179
  };
219
180
  }
220
181
  //#endregion
182
+ //#region extensions/msteams/src/action-threading.ts
183
+ function stripConversationPrefix(raw) {
184
+ const trimmed = raw.trim();
185
+ if (/^conversation:/i.test(trimmed)) return trimmed.slice(13).trim();
186
+ return trimmed;
187
+ }
188
+ /** Normalize Teams conversation targets for equality (strips `conversation:` and `;messageid=`). */
189
+ function normalizeMSTeamsThreadingTarget(raw) {
190
+ const value = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(raw);
191
+ if (!value) return;
192
+ return require_resolve_allowlist.normalizeMSTeamsConversationId(stripConversationPrefix(value));
193
+ }
194
+ function extractMSTeamsResultConversationId(value) {
195
+ if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(value)) return;
196
+ const direct = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(value.conversationId);
197
+ if (direct) return direct;
198
+ const receipt = (0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(value.receipt) ? value.receipt : void 0;
199
+ if (!receipt) return;
200
+ const candidates = [...Array.isArray(receipt.raw) ? receipt.raw : [], ...Array.isArray(receipt.parts) ? receipt.parts.map((part) => (0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(part) ? part.raw : void 0) : []];
201
+ for (const candidate of candidates) {
202
+ if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(candidate)) continue;
203
+ const conversationId = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(candidate.conversationId);
204
+ if (conversationId) return conversationId;
205
+ }
206
+ }
207
+ /** Recover the actual Teams conversation resolved by a successful tool send. */
208
+ function extractMSTeamsToolSendResult(result, _send) {
209
+ const details = (0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(result) && (0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(result.details) ? result.details : void 0;
210
+ const conversationId = extractMSTeamsResultConversationId(details && (0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(details.result) ? details.result : void 0);
211
+ if (!conversationId) return null;
212
+ const normalizedConversationId = require_resolve_allowlist.normalizeMSTeamsConversationId(stripConversationPrefix(conversationId));
213
+ return normalizedConversationId ? { to: `conversation:${normalizedConversationId}` } : null;
214
+ }
215
+ function msteamsContextTargetsMatch(target, context) {
216
+ const normalizedTarget = normalizeMSTeamsThreadingTarget(target);
217
+ if (!normalizedTarget) return false;
218
+ const currentChannel = normalizeMSTeamsThreadingTarget(context.currentChannelId);
219
+ if (currentChannel && currentChannel === normalizedTarget) return true;
220
+ const currentMessaging = normalizeMSTeamsThreadingTarget(context.currentMessagingTarget);
221
+ return Boolean(currentMessaging && currentMessaging === normalizedTarget);
222
+ }
223
+ function resolveMSTeamsAutoThreadId(params) {
224
+ const explicitThreadId = require_resolve_allowlist.extractMSTeamsConversationMessageId(params.to);
225
+ if (explicitThreadId) return explicitThreadId;
226
+ const context = params.toolContext;
227
+ if (!context?.currentChannelId && !context?.currentMessagingTarget) return;
228
+ if (!msteamsContextTargetsMatch(params.to, context)) return;
229
+ const graphTarget = context.currentGraphChannelId ?? context.currentMessagingTarget;
230
+ const { team, channel } = graphTarget ? require_resolve_allowlist.parseMSTeamsTeamChannelInput(graphTarget) : {
231
+ team: void 0,
232
+ channel: void 0
233
+ };
234
+ const routeConfig = resolveMSTeamsRouteConfig({
235
+ cfg: params.cfg,
236
+ teamId: team,
237
+ conversationId: channel,
238
+ allowNameMatching: false
239
+ });
240
+ const { replyStyle } = resolveMSTeamsReplyPolicy({
241
+ isDirectMessage: false,
242
+ globalConfig: params.cfg,
243
+ teamConfig: routeConfig.teamConfig,
244
+ channelConfig: routeConfig.channelConfig
245
+ });
246
+ if (replyStyle === "top-level") return;
247
+ if (!context.currentThreadTs) return;
248
+ if (context.replyToMode !== "all" && !(0, openclaw_plugin_sdk_reply_reference.isSingleUseReplyToMode)(context.replyToMode ?? "off")) return;
249
+ if ((0, openclaw_plugin_sdk_reply_reference.isSingleUseReplyToMode)(context.replyToMode ?? "off") && context.hasRepliedRef?.value) return;
250
+ return context.currentThreadTs;
251
+ }
252
+ //#endregion
253
+ //#region extensions/msteams/src/approval-auth.ts
254
+ const MSTEAMS_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
255
+ function normalizeMSTeamsApproverId(value) {
256
+ const normalized = require_resolve_allowlist.normalizeMSTeamsMessagingTarget(String(value));
257
+ const id = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(normalized?.startsWith("user:") ? normalized.slice(5) : normalized);
258
+ return id && MSTEAMS_ID_RE.test(id) ? id : void 0;
259
+ }
260
+ function resolveMSTeamsChannelConfig(cfg) {
261
+ return cfg.channels?.msteams;
262
+ }
263
+ const msTeamsApprovalAuth = (0, openclaw_plugin_sdk_approval_auth_runtime.createChannelApprovalAuth)({
264
+ channelLabel: "Microsoft Teams",
265
+ resolveInputs: ({ cfg }) => {
266
+ const channel = resolveMSTeamsChannelConfig(cfg);
267
+ return {
268
+ allowFrom: channel?.allowFrom,
269
+ defaultTo: channel?.defaultTo
270
+ };
271
+ },
272
+ normalizeApprover: normalizeMSTeamsApproverId,
273
+ normalizeSenderId: (value) => {
274
+ const trimmed = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(value);
275
+ if (!trimmed) return;
276
+ return MSTEAMS_ID_RE.test(trimmed) ? trimmed : void 0;
277
+ }
278
+ }).approvalAuth;
279
+ //#endregion
280
+ //#region extensions/msteams/src/doctor.ts
281
+ const isMSTeamsMutableAllowEntry = (0, openclaw_plugin_sdk_channel_policy.buildMutableAllowEntryDetector)({
282
+ prefixes: ["msteams:", "user:"],
283
+ stableIdPattern: /^[^\s@]+$/
284
+ });
285
+ const collectMSTeamsMutableAllowlistWarnings = (0, openclaw_plugin_sdk_channel_policy.createDangerousNameMatchingMutableAllowlistWarningCollector)({
286
+ channel: "msteams",
287
+ detector: isMSTeamsMutableAllowEntry,
288
+ collectLists: (scope) => (0, openclaw_plugin_sdk_channel_policy.collectStandardAllowlistLists)(scope)
289
+ });
290
+ //#endregion
221
291
  //#region extensions/msteams/src/presentation.ts
222
292
  const MSTEAMS_PRESENTATION_CAPABILITIES = {
223
293
  supported: true,
@@ -434,8 +504,8 @@ async function resolveAllowedChannelTarget(cfg, target) {
434
504
  allowNameMatching: (0, openclaw_plugin_sdk_dangerous_name_runtime.isDangerousNameMatchingEnabled)(teams)
435
505
  });
436
506
  const stableTarget = await resolveStableChannelTarget(cfg, target);
507
+ if (!directRoute.allowlistConfigured && groupPolicy !== "open" && stableTarget) throw new openclaw_plugin_sdk_channel_actions.ToolAuthorizationError("Microsoft Teams read target is not allowed. Configure channels.msteams.teams.<team>.channels for this channel, or deliberately set channels.msteams.groupPolicy to \"open\".");
437
508
  if (directRoute.allowed) return stableTarget;
438
- if (!directRoute.allowlistConfigured) return groupPolicy === "open" ? stableTarget : void 0;
439
509
  if (!stableTarget || !teams?.teams) return;
440
510
  const [stableTeamId, stableChannelId] = stableTarget.split("/", 2);
441
511
  if (!stableTeamId || !stableChannelId) return;
@@ -545,20 +615,32 @@ function resolveMSTeamsRouteSessionKey(params) {
545
615
  }
546
616
  //#endregion
547
617
  //#region extensions/msteams/src/session-route.ts
618
+ function inferMSTeamsTargetChatType(raw) {
619
+ const target = (0, openclaw_plugin_sdk_channel_core.stripChannelTargetPrefix)(raw, "msteams", "teams");
620
+ if (!target) return;
621
+ const lower = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(target);
622
+ const rawId = (0, openclaw_plugin_sdk_channel_core.stripTargetKindPrefix)(target);
623
+ if (!rawId) return;
624
+ const conversationId = require_resolve_allowlist.normalizeMSTeamsConversationId(rawId);
625
+ if (lower.startsWith("user:") || /^[0-9a-f-]{16,}$/i.test(conversationId)) return "direct";
626
+ if (/@thread\.tacv2/i.test(conversationId)) return "channel";
627
+ return /^19:.+@thread\.(?:skype|v2)$/i.test(conversationId) ? "group" : void 0;
628
+ }
548
629
  function resolveMSTeamsOutboundSessionRoute(params) {
549
630
  const trimmed = (0, openclaw_plugin_sdk_channel_core.stripChannelTargetPrefix)(params.target, "msteams", "teams");
550
631
  if (!trimmed) return null;
551
- const isUser = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(trimmed).startsWith("user:");
632
+ const resolvedKind = params.resolvedTarget?.kind;
633
+ const targetChatType = inferMSTeamsTargetChatType(trimmed);
634
+ const isUser = resolvedKind === "user" || targetChatType === "direct";
552
635
  const rawId = (0, openclaw_plugin_sdk_channel_core.stripTargetKindPrefix)(trimmed);
553
636
  if (!rawId) return null;
554
637
  const conversationId = require_resolve_allowlist.normalizeMSTeamsConversationId(rawId);
555
- const isChannel = !isUser && /@thread\.tacv2/i.test(conversationId);
638
+ const isChannel = !isUser && targetChatType === "channel";
556
639
  const embeddedThreadId = require_resolve_allowlist.extractMSTeamsConversationMessageId(rawId);
557
640
  const explicitThreadId = params.threadId ?? params.replyToId;
558
641
  const channelThreadId = embeddedThreadId ?? (explicitThreadId !== void 0 && explicitThreadId !== null ? String(explicitThreadId) : void 0);
559
- const resolvedKind = params.resolvedTarget?.kind;
560
642
  const isCanonicalUserId = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(conversationId);
561
- const recipientSessionExact = (isUser || resolvedKind === "user") && isCanonicalUserId || (isChannel ? channelThreadId !== void 0 : resolvedKind === "group");
643
+ const recipientSessionExact = isUser && isCanonicalUserId || (isChannel ? channelThreadId !== void 0 : resolvedKind === "group");
562
644
  const route = (0, openclaw_plugin_sdk_channel_core.buildChannelOutboundSessionRoute)({
563
645
  cfg: params.cfg,
564
646
  agentId: params.agentId,
@@ -604,7 +686,7 @@ const collectMSTeamsSecurityWarnings = (0, openclaw_plugin_sdk_channel_policy.cr
604
686
  resolveGroupPolicy: ({ cfg }) => cfg.channels?.msteams?.groupPolicy,
605
687
  collect: ({ groupPolicy }) => groupPolicy === "open" ? ["- MS Teams groups: groupPolicy=\"open\" allows any member to trigger (mention-gated). Set channels.msteams.groupPolicy=\"allowlist\" + channels.msteams.groupAllowFrom to restrict senders."] : []
606
688
  });
607
- const loadMSTeamsChannelRuntime = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeNamedExport)(() => Promise.resolve().then(() => require("./channel.runtime-DjY6d_hd.cjs")), "msTeamsChannelRuntime");
689
+ const loadMSTeamsChannelRuntime = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeNamedExport)(() => Promise.resolve().then(() => require("./channel.runtime-BJmueA4q.cjs")), "msTeamsChannelRuntime");
608
690
  function jsonActionResult(data) {
609
691
  return {
610
692
  content: [{
@@ -700,7 +782,7 @@ function resolveActionContent(params) {
700
782
  return typeof params.text === "string" ? params.text : typeof params.content === "string" ? params.content : typeof params.message === "string" ? params.message : "";
701
783
  }
702
784
  function readOptionalTrimmedString(params, key) {
703
- return typeof params[key] === "string" ? params[key].trim() || void 0 : void 0;
785
+ return (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(params[key]);
704
786
  }
705
787
  function resolveActionUploadFilePath(params) {
706
788
  for (const key of [
@@ -712,64 +794,31 @@ function resolveActionUploadFilePath(params) {
712
794
  if (value.trim()) return value;
713
795
  }
714
796
  }
715
- function resolveRequiredActionTarget(params) {
716
- const to = params.graphOnly ? resolveGraphActionTarget(params.toolParams, params.currentChannelId, params.currentGraphChannelId, params.currentChatType) : resolveActionTarget(params.toolParams, params.currentChannelId);
797
+ function resolveMSTeamsActionTarget(params) {
798
+ return params.graphOnly ? resolveGraphActionTarget(params.toolParams, params.currentChannelId, params.currentGraphChannelId, params.currentChatType) : resolveActionTarget(params.toolParams, params.currentChannelId);
799
+ }
800
+ async function runWithRequiredActionTarget(params) {
801
+ const to = resolveMSTeamsActionTarget(params);
717
802
  if (!to) return actionError(`${params.actionLabel} requires a target (to).`);
718
- return to;
803
+ return await params.run(to);
719
804
  }
720
- function resolveRequiredActionMessageTarget(params) {
721
- const to = params.graphOnly ? resolveGraphActionTarget(params.toolParams, params.currentChannelId, params.currentGraphChannelId, params.currentChatType) : resolveActionTarget(params.toolParams, params.currentChannelId);
805
+ async function runWithRequiredActionMessageTarget(params) {
806
+ const to = resolveMSTeamsActionTarget(params);
722
807
  const messageId = resolveActionMessageId(params.toolParams);
723
808
  if (!to || !messageId) return actionError(`${params.actionLabel} requires a target (to) and messageId.`);
724
- return {
809
+ return await params.run({
725
810
  to,
726
811
  messageId
727
- };
812
+ });
728
813
  }
729
- function resolveRequiredActionPinnedMessageTarget(params) {
730
- const to = params.graphOnly ? resolveGraphActionTarget(params.toolParams, params.currentChannelId, params.currentGraphChannelId, params.currentChatType) : resolveActionTarget(params.toolParams, params.currentChannelId);
814
+ async function runWithRequiredActionPinnedMessageTarget(params) {
815
+ const to = resolveMSTeamsActionTarget(params);
731
816
  const pinnedMessageId = resolveActionPinnedMessageId(params.toolParams);
732
817
  if (!to || !pinnedMessageId) return actionError(`${params.actionLabel} requires a target (to) and pinnedMessageId.`);
733
- return {
818
+ return await params.run({
734
819
  to,
735
820
  pinnedMessageId
736
- };
737
- }
738
- async function runWithRequiredActionTarget(params) {
739
- const to = resolveRequiredActionTarget({
740
- actionLabel: params.actionLabel,
741
- toolParams: params.toolParams,
742
- currentChannelId: params.currentChannelId,
743
- currentGraphChannelId: params.currentGraphChannelId,
744
- currentChatType: params.currentChatType,
745
- graphOnly: params.graphOnly
746
- });
747
- if (typeof to !== "string") return to;
748
- return await params.run(to);
749
- }
750
- async function runWithRequiredActionMessageTarget(params) {
751
- const target = resolveRequiredActionMessageTarget({
752
- actionLabel: params.actionLabel,
753
- toolParams: params.toolParams,
754
- currentChannelId: params.currentChannelId,
755
- currentGraphChannelId: params.currentGraphChannelId,
756
- currentChatType: params.currentChatType,
757
- graphOnly: params.graphOnly
758
- });
759
- if ("isError" in target) return target;
760
- return await params.run(target);
761
- }
762
- async function runWithRequiredActionPinnedMessageTarget(params) {
763
- const target = resolveRequiredActionPinnedMessageTarget({
764
- actionLabel: params.actionLabel,
765
- toolParams: params.toolParams,
766
- currentChannelId: params.currentChannelId,
767
- currentGraphChannelId: params.currentGraphChannelId,
768
- currentChatType: params.currentChatType,
769
- graphOnly: params.graphOnly
770
821
  });
771
- if ("isError" in target) return target;
772
- return await params.run(target);
773
822
  }
774
823
  function describeMSTeamsMessageTool({ cfg }) {
775
824
  const enabled = cfg.channels?.msteams?.enabled !== false && Boolean(require_resolve_allowlist.resolveMSTeamsCredentials(cfg.channels?.msteams));
@@ -882,12 +931,12 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
882
931
  warnOnEmptyGroupSenderAllowlist: true,
883
932
  collectMutableAllowlistWarnings: collectMSTeamsMutableAllowlistWarnings
884
933
  },
885
- setup: require_setup_surface.msteamsSetupAdapter,
886
934
  setupContract: require_setup_surface.msteamsSetupContract,
887
935
  messaging: {
888
936
  targetPrefixes: ["msteams", "teams"],
889
937
  directTargetStyle: "user-prefixed",
890
938
  normalizeTarget: require_resolve_allowlist.normalizeMSTeamsMessagingTarget,
939
+ inferTargetChatType: ({ to }) => inferMSTeamsTargetChatType(to),
891
940
  resolveOutboundSessionRoute: (params) => resolveMSTeamsOutboundSessionRoute(params),
892
941
  targetResolver: {
893
942
  looksLikeId: (raw) => require_resolve_allowlist.looksLikeMSTeamsTargetId(raw),
@@ -1039,12 +1088,18 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1039
1088
  } },
1040
1089
  actions: {
1041
1090
  describeMessageTool: describeMSTeamsMessageTool,
1091
+ extractToolSendResult: ({ result, send }) => extractMSTeamsToolSendResult(result, send),
1042
1092
  requiresTrustedRequesterSender: ({ action, toolContext }) => (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(toolContext?.currentChannelProvider)?.toLowerCase() === "msteams" && MSTEAMS_GROUP_MANAGEMENT_ACTIONS.has(action),
1043
1093
  handleAction: async (ctx) => {
1044
1094
  if (MSTEAMS_GROUP_MANAGEMENT_ACTIONS.has(ctx.action)) {
1045
1095
  const authError = requireMSTeamsGroupManagementAuthorization(ctx);
1046
1096
  if (authError) return authError;
1047
1097
  }
1098
+ const authorizeActionTarget = (target) => assertMSTeamsReadTargetAllowed({
1099
+ cfg: ctx.cfg,
1100
+ ctx,
1101
+ target
1102
+ });
1048
1103
  const presentation = ctx.action === "send" ? (0, openclaw_plugin_sdk_interactive_runtime.normalizeMessagePresentation)(ctx.params.presentation) : void 0;
1049
1104
  if (ctx.action === "send" && presentation) {
1050
1105
  const card = buildMSTeamsPresentationCard({
@@ -1089,6 +1144,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1089
1144
  text: resolveActionContent(ctx.params),
1090
1145
  mediaUrl,
1091
1146
  filename: readOptionalTrimmedString(ctx.params, "filename") ?? readOptionalTrimmedString(ctx.params, "title"),
1147
+ mediaAccess: ctx.mediaAccess,
1092
1148
  mediaLocalRoots: ctx.mediaLocalRoots,
1093
1149
  mediaReadFile: ctx.mediaReadFile
1094
1150
  });
@@ -1116,11 +1172,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1116
1172
  toolParams: ctx.params,
1117
1173
  currentChannelId: ctx.toolContext?.currentChannelId,
1118
1174
  run: async (target) => {
1119
- const to = await assertMSTeamsReadTargetAllowed({
1120
- cfg: ctx.cfg,
1121
- ctx,
1122
- target: target.to
1123
- });
1175
+ const to = await authorizeActionTarget(target.to);
1124
1176
  const { editMessageMSTeams } = await loadMSTeamsChannelRuntime();
1125
1177
  return jsonMSTeamsConversationResult((await editMessageMSTeams({
1126
1178
  cfg: ctx.cfg,
@@ -1136,11 +1188,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1136
1188
  toolParams: ctx.params,
1137
1189
  currentChannelId: ctx.toolContext?.currentChannelId,
1138
1190
  run: async (target) => {
1139
- const to = await assertMSTeamsReadTargetAllowed({
1140
- cfg: ctx.cfg,
1141
- ctx,
1142
- target: target.to
1143
- });
1191
+ const to = await authorizeActionTarget(target.to);
1144
1192
  const { deleteMessageMSTeams } = await loadMSTeamsChannelRuntime();
1145
1193
  return jsonMSTeamsConversationResult((await deleteMessageMSTeams({
1146
1194
  cfg: ctx.cfg,
@@ -1149,19 +1197,18 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1149
1197
  })).conversationId);
1150
1198
  }
1151
1199
  });
1152
- if (ctx.action === "read") return await runWithRequiredActionMessageTarget({
1153
- actionLabel: "Read",
1200
+ const graphActionTarget = {
1154
1201
  toolParams: ctx.params,
1155
1202
  currentChannelId: ctx.toolContext?.currentChannelId,
1156
1203
  currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
1157
1204
  currentChatType: ctx.toolContext?.currentChatType,
1158
- graphOnly: true,
1205
+ graphOnly: true
1206
+ };
1207
+ if (ctx.action === "read") return await runWithRequiredActionMessageTarget({
1208
+ actionLabel: "Read",
1209
+ ...graphActionTarget,
1159
1210
  run: async (target) => {
1160
- const to = await assertMSTeamsReadTargetAllowed({
1161
- cfg: ctx.cfg,
1162
- ctx,
1163
- target: target.to
1164
- });
1211
+ const to = await authorizeActionTarget(target.to);
1165
1212
  const { getMessageMSTeams } = await loadMSTeamsChannelRuntime();
1166
1213
  return jsonMSTeamsOkActionResult("read", { message: await getMessageMSTeams({
1167
1214
  cfg: ctx.cfg,
@@ -1172,17 +1219,9 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1172
1219
  });
1173
1220
  if (ctx.action === "pin") return await runWithRequiredActionMessageTarget({
1174
1221
  actionLabel: "Pin",
1175
- toolParams: ctx.params,
1176
- currentChannelId: ctx.toolContext?.currentChannelId,
1177
- currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
1178
- currentChatType: ctx.toolContext?.currentChatType,
1179
- graphOnly: true,
1222
+ ...graphActionTarget,
1180
1223
  run: async (target) => {
1181
- const to = await assertMSTeamsReadTargetAllowed({
1182
- cfg: ctx.cfg,
1183
- ctx,
1184
- target: target.to
1185
- });
1224
+ const to = await authorizeActionTarget(target.to);
1186
1225
  const { pinMessageMSTeams } = await loadMSTeamsChannelRuntime();
1187
1226
  return jsonMSTeamsActionResult("pin", await pinMessageMSTeams({
1188
1227
  cfg: ctx.cfg,
@@ -1193,17 +1232,9 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1193
1232
  });
1194
1233
  if (ctx.action === "unpin") return await runWithRequiredActionPinnedMessageTarget({
1195
1234
  actionLabel: "Unpin",
1196
- toolParams: ctx.params,
1197
- currentChannelId: ctx.toolContext?.currentChannelId,
1198
- currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
1199
- currentChatType: ctx.toolContext?.currentChatType,
1200
- graphOnly: true,
1235
+ ...graphActionTarget,
1201
1236
  run: async (target) => {
1202
- const to = await assertMSTeamsReadTargetAllowed({
1203
- cfg: ctx.cfg,
1204
- ctx,
1205
- target: target.to
1206
- });
1237
+ const to = await authorizeActionTarget(target.to);
1207
1238
  const { unpinMessageMSTeams } = await loadMSTeamsChannelRuntime();
1208
1239
  return jsonMSTeamsActionResult("unpin", await unpinMessageMSTeams({
1209
1240
  cfg: ctx.cfg,
@@ -1214,17 +1245,9 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1214
1245
  });
1215
1246
  if (ctx.action === "list-pins") return await runWithRequiredActionTarget({
1216
1247
  actionLabel: "List-pins",
1217
- toolParams: ctx.params,
1218
- currentChannelId: ctx.toolContext?.currentChannelId,
1219
- currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
1220
- currentChatType: ctx.toolContext?.currentChatType,
1221
- graphOnly: true,
1248
+ ...graphActionTarget,
1222
1249
  run: async (to) => {
1223
- const allowedTarget = await assertMSTeamsReadTargetAllowed({
1224
- cfg: ctx.cfg,
1225
- ctx,
1226
- target: to
1227
- });
1250
+ const allowedTarget = await authorizeActionTarget(to);
1228
1251
  const { listPinsMSTeams } = await loadMSTeamsChannelRuntime();
1229
1252
  return jsonMSTeamsOkActionResult("list-pins", await listPinsMSTeams({
1230
1253
  cfg: ctx.cfg,
@@ -1234,11 +1257,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1234
1257
  });
1235
1258
  if (ctx.action === "react") return await runWithRequiredActionMessageTarget({
1236
1259
  actionLabel: "React",
1237
- toolParams: ctx.params,
1238
- currentChannelId: ctx.toolContext?.currentChannelId,
1239
- currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
1240
- currentChatType: ctx.toolContext?.currentChatType,
1241
- graphOnly: true,
1260
+ ...graphActionTarget,
1242
1261
  run: async (target) => {
1243
1262
  const emoji = typeof ctx.params.emoji === "string" ? ctx.params.emoji.trim() : "";
1244
1263
  const remove = typeof ctx.params.remove === "boolean" ? ctx.params.remove : false;
@@ -1253,11 +1272,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1253
1272
  validTypes: [...MSTEAMS_REACTION_TYPES]
1254
1273
  }
1255
1274
  };
1256
- const to = await assertMSTeamsReadTargetAllowed({
1257
- cfg: ctx.cfg,
1258
- ctx,
1259
- target: target.to
1260
- });
1275
+ const to = await authorizeActionTarget(target.to);
1261
1276
  if (remove) {
1262
1277
  const { unreactMessageMSTeams } = await loadMSTeamsChannelRuntime();
1263
1278
  return jsonMSTeamsActionResult("react", {
@@ -1285,17 +1300,9 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1285
1300
  });
1286
1301
  if (ctx.action === "reactions") return await runWithRequiredActionMessageTarget({
1287
1302
  actionLabel: "Reactions",
1288
- toolParams: ctx.params,
1289
- currentChannelId: ctx.toolContext?.currentChannelId,
1290
- currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
1291
- currentChatType: ctx.toolContext?.currentChatType,
1292
- graphOnly: true,
1303
+ ...graphActionTarget,
1293
1304
  run: async (target) => {
1294
- const to = await assertMSTeamsReadTargetAllowed({
1295
- cfg: ctx.cfg,
1296
- ctx,
1297
- target: target.to
1298
- });
1305
+ const to = await authorizeActionTarget(target.to);
1299
1306
  const { listReactionsMSTeams } = await loadMSTeamsChannelRuntime();
1300
1307
  return jsonMSTeamsOkActionResult("reactions", await listReactionsMSTeams({
1301
1308
  cfg: ctx.cfg,
@@ -1306,17 +1313,9 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1306
1313
  });
1307
1314
  if (ctx.action === "search") return await runWithRequiredActionTarget({
1308
1315
  actionLabel: "Search",
1309
- toolParams: ctx.params,
1310
- currentChannelId: ctx.toolContext?.currentChannelId,
1311
- currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
1312
- currentChatType: ctx.toolContext?.currentChatType,
1313
- graphOnly: true,
1316
+ ...graphActionTarget,
1314
1317
  run: async (to) => {
1315
- const allowedTarget = await assertMSTeamsReadTargetAllowed({
1316
- cfg: ctx.cfg,
1317
- ctx,
1318
- target: to
1319
- });
1318
+ const allowedTarget = await authorizeActionTarget(to);
1320
1319
  const query = resolveActionQuery(ctx.params);
1321
1320
  if (!query) return actionError("Search requires a target (to) and query.");
1322
1321
  const limit = typeof ctx.params.limit === "number" ? ctx.params.limit : void 0;
@@ -1336,17 +1335,9 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1336
1335
  if (!userId) return actionError("member-info requires a userId.");
1337
1336
  return await runWithRequiredActionTarget({
1338
1337
  actionLabel: "member-info",
1339
- toolParams: ctx.params,
1340
- currentChannelId: ctx.toolContext?.currentChannelId,
1341
- currentGraphChannelId: resolveCurrentGraphActionTarget(ctx.toolContext),
1342
- currentChatType: ctx.toolContext?.currentChatType,
1343
- graphOnly: true,
1338
+ ...graphActionTarget,
1344
1339
  run: async (target) => {
1345
- const to = await assertMSTeamsReadTargetAllowed({
1346
- cfg: ctx.cfg,
1347
- ctx,
1348
- target
1349
- });
1340
+ const to = await authorizeActionTarget(target);
1350
1341
  const currentRequesterId = isCurrentMSTeamsReadTarget({
1351
1342
  ctx,
1352
1343
  target: to
@@ -1379,11 +1370,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1379
1370
  const teamId = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.params.teamId) ?? "";
1380
1371
  const channelId = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.params.channelId) ?? "";
1381
1372
  if (!teamId || !channelId) return actionError("channel-info requires teamId and channelId.");
1382
- const [graphTeamId, graphChannelId] = (await assertMSTeamsReadTargetAllowed({
1383
- cfg: ctx.cfg,
1384
- ctx,
1385
- target: `${teamId}/${channelId}`
1386
- })).split("/", 2);
1373
+ const [graphTeamId, graphChannelId] = (await authorizeActionTarget(`${teamId}/${channelId}`)).split("/", 2);
1387
1374
  if (!graphTeamId || !graphChannelId) throw new Error("Authorized Microsoft Teams channel target is invalid.");
1388
1375
  const { getChannelInfoMSTeams } = await loadMSTeamsChannelRuntime();
1389
1376
  return jsonMSTeamsOkActionResult("channel-info", { channelInfo: (await getChannelInfoMSTeams({
@@ -1484,17 +1471,19 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1484
1471
  })
1485
1472
  }),
1486
1473
  gateway: { startAccount: async (ctx) => {
1487
- const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./src-B_BdEvcr.cjs"));
1474
+ const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./src-Bz9wY0Mr.cjs"));
1488
1475
  const port = ctx.cfg.channels?.msteams?.webhook?.port ?? 3978;
1489
- ctx.setStatus({
1476
+ const statusSink = (0, openclaw_plugin_sdk_channel_outbound.createAccountStatusSink)({
1490
1477
  accountId: ctx.accountId,
1491
- port
1478
+ setStatus: ctx.setStatus
1492
1479
  });
1480
+ statusSink({ port });
1493
1481
  ctx.log?.info(`starting provider (port ${port})`);
1494
1482
  return monitorMSTeamsProvider({
1495
1483
  cfg: ctx.cfg,
1496
1484
  runtime: ctx.runtime,
1497
- abortSignal: ctx.abortSignal
1485
+ abortSignal: ctx.abortSignal,
1486
+ statusSink
1498
1487
  });
1499
1488
  } }
1500
1489
  },
@@ -1512,18 +1501,29 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1512
1501
  });
1513
1502
  }
1514
1503
  } },
1515
- threading: { buildToolContext: ({ context, hasRepliedRef }) => {
1516
- const nativeChannelId = context.NativeChannelId?.trim();
1517
- const hasChannelRoute = Boolean(nativeChannelId && nativeChannelId.includes("/"));
1518
- return {
1519
- currentChannelId: (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(context.To),
1520
- currentChatType: context.ChatType === "direct" || context.ChatType === "group" || context.ChatType === "channel" ? context.ChatType : void 0,
1521
- currentMessagingTarget: hasChannelRoute ? nativeChannelId : void 0,
1522
- currentGraphChannelId: hasChannelRoute ? nativeChannelId : void 0,
1523
- currentThreadTs: context.ReplyToId,
1524
- hasRepliedRef
1525
- };
1526
- } },
1504
+ threading: {
1505
+ matchesToolContextTarget: ({ target, toolContext }) => msteamsContextTargetsMatch(target, toolContext),
1506
+ buildToolContext: ({ context, hasRepliedRef }) => {
1507
+ const nativeChannelId = context.NativeChannelId?.trim();
1508
+ const hasChannelRoute = Boolean(nativeChannelId && nativeChannelId.includes("/"));
1509
+ const isChannel = context.ChatType === "channel";
1510
+ const currentThreadTs = (context.MessageThreadId != null ? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(String(context.MessageThreadId)) : void 0) ?? (isChannel ? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(context.ReplyToId) : void 0);
1511
+ return {
1512
+ currentChannelId: (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(context.To),
1513
+ currentChatType: context.ChatType === "direct" || context.ChatType === "group" || context.ChatType === "channel" ? context.ChatType : void 0,
1514
+ currentMessagingTarget: hasChannelRoute ? nativeChannelId : void 0,
1515
+ currentGraphChannelId: hasChannelRoute ? nativeChannelId : void 0,
1516
+ currentThreadTs,
1517
+ ...currentThreadTs ? { replyToMode: "all" } : {},
1518
+ hasRepliedRef
1519
+ };
1520
+ },
1521
+ resolveAutoThreadId: ({ cfg, to, toolContext }) => resolveMSTeamsAutoThreadId({
1522
+ cfg: cfg.channels?.msteams,
1523
+ to,
1524
+ toolContext
1525
+ })
1526
+ },
1527
1527
  outbound: msteamsChannelOutbound
1528
1528
  });
1529
1529
  //#endregion
@@ -1,3 +1,3 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_channel = require("./channel-C7QxRjBW.cjs");
2
+ const require_channel = require("./channel-DfCbi0d_.cjs");
3
3
  exports.msteamsPlugin = require_channel.msteamsPlugin;