@openclaw/msteams 2026.10.5-beta.3 → 2026.10.10-beta.1

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.
Files changed (35) hide show
  1. package/dist/.setup/{adapter.runtime-JoPydWqP.cjs → adapter.runtime-B-6Q3nMI.cjs} +6 -4
  2. package/dist/.setup/{approval-handler.runtime-bUN9icMr.cjs → approval-handler.runtime-DccVf5AY.cjs} +16 -6
  3. package/dist/.setup/{bot-framework-service-url-CPp4d-Q6.cjs → bot-framework-service-url-B3FWn2SV.cjs} +13 -0
  4. package/dist/.setup/{channel-Cifn9fsv.cjs → channel-B7Gy3QUW.cjs} +261 -175
  5. package/dist/.setup/{channel.runtime-DWRAolil.cjs → channel.runtime-DzKeQAqd.cjs} +84 -49
  6. package/dist/.setup/channel.setup-B5ClEcNI.cjs +990 -0
  7. package/dist/.setup/config-schema-CkKdphSp.cjs +293 -0
  8. package/dist/.setup/{conversation-store-state-DprmOfl7.cjs → conversation-store-state-C3__T9mK.cjs} +79 -91
  9. package/dist/.setup/delegated-state-Bv5cWuec.cjs +110 -0
  10. package/dist/.setup/{monitor-C9x_CJhY.cjs → monitor-CzRI-Hsc.cjs} +283 -240
  11. package/dist/.setup/{oauth-CWJ85AMw.cjs → oauth-D9u8sPCD.cjs} +1 -1
  12. package/dist/.setup/{reaction-types-Ig9sQJuR.cjs → reaction-types-DSQWVA4Z.cjs} +15 -9
  13. package/dist/.setup/{resolve-allowlist-DdDBVCzl.cjs → resolve-allowlist-tYgAHx0t.cjs} +252 -38
  14. package/dist/.setup/{secret-contract-api-ChQdBeU1.cjs → secret-contract-api-YY3v6MP8.cjs} +1 -1
  15. package/dist/.setup/secret-contract-api-wAyY5UHv.cjs +85 -0
  16. package/dist/.setup/{send-rJpcVtRp.cjs → send-Bgm8RYUa.cjs} +45 -24
  17. package/dist/.setup/{setup-plugin-api-DfoVOqMJ.cjs → setup-plugin-api-BACfeF7_.cjs} +1 -1
  18. package/dist/.setup/{thread-session-B74FC1Id.cjs → thread-session-C7KTMwLU.cjs} +11 -4
  19. package/dist/.setup/token-config-bEpua_Q7.cjs +93 -0
  20. package/dist/api.cjs +2 -2
  21. package/dist/channel-config-api.cjs +1 -1
  22. package/dist/channel-plugin-api.cjs +1 -1
  23. package/dist/directory-contract-api.cjs +30 -22
  24. package/dist/doctor-contract-api.cjs +11 -10
  25. package/dist/qa-runner-api.cjs +1 -1
  26. package/dist/runtime-api.cjs +2 -2
  27. package/dist/secret-contract-api.cjs +1 -1
  28. package/dist/setup-entry.cjs +2 -2
  29. package/dist/setup-plugin-api.cjs +1 -1
  30. package/openclaw.plugin.json +715 -0
  31. package/package.json +57 -6
  32. package/dist/.setup/channel.setup-BjbHugkL.cjs +0 -632
  33. package/dist/.setup/config-schema-Dk0mRIam.cjs +0 -160
  34. package/dist/.setup/secret-contract-api-ipiUsANg.cjs +0 -28
  35. package/dist/.setup/token-config-CqIh8z7Q.cjs +0 -138
@@ -1,9 +1,9 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-BloeesfJ.cjs");
2
+ const require_resolve_allowlist = require("./resolve-allowlist-tYgAHx0t.cjs");
2
3
  require("../runtime-api.cjs");
3
- const require_resolve_allowlist = require("./resolve-allowlist-DdDBVCzl.cjs");
4
4
  const require_directory_contract_api = require("../directory-contract-api.cjs");
5
- const require_thread_session = require("./thread-session-B74FC1Id.cjs");
6
- const require_channel_setup = require("./channel.setup-BjbHugkL.cjs");
5
+ const require_thread_session = require("./thread-session-C7KTMwLU.cjs");
6
+ const require_channel_setup = require("./channel.setup-B5ClEcNI.cjs");
7
7
  let openclaw_plugin_sdk_approval_handler_adapter_runtime = require("openclaw/plugin-sdk/approval-handler-adapter-runtime");
8
8
  let openclaw_plugin_sdk_channel_actions = require("openclaw/plugin-sdk/channel-actions");
9
9
  let openclaw_plugin_sdk_channel_core = require("openclaw/plugin-sdk/channel-core");
@@ -17,12 +17,12 @@ let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime
17
17
  let openclaw_plugin_sdk_status_helpers = require("openclaw/plugin-sdk/status-helpers");
18
18
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
19
19
  let openclaw_plugin_sdk_tool_results = require("openclaw/plugin-sdk/tool-results");
20
- let typebox = require("typebox");
21
20
  let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
22
21
  let openclaw_plugin_sdk_text_chunking = require("openclaw/plugin-sdk/text-chunking");
23
22
  let openclaw_plugin_sdk_reply_reference = require("openclaw/plugin-sdk/reply-reference");
24
23
  let openclaw_plugin_sdk_approval_delivery_runtime = require("openclaw/plugin-sdk/approval-delivery-runtime");
25
24
  let openclaw_plugin_sdk_approval_native_runtime = require("openclaw/plugin-sdk/approval-native-runtime");
25
+ let typebox = require("typebox");
26
26
  let openclaw_plugin_sdk_channel_targets = require("openclaw/plugin-sdk/channel-targets");
27
27
  let openclaw_plugin_sdk_dangerous_name_runtime = require("openclaw/plugin-sdk/dangerous-name-runtime");
28
28
  let openclaw_plugin_sdk_runtime_group_policy = require("openclaw/plugin-sdk/runtime-group-policy");
@@ -122,7 +122,7 @@ function resolveMSTeamsRouteConfig(params) {
122
122
  };
123
123
  }
124
124
  function resolveMSTeamsGroupToolPolicy(params) {
125
- const cfg = params.cfg.channels?.msteams;
125
+ const cfg = require_resolve_allowlist.resolveMSTeamsAccountConfig(params.cfg, params.accountId);
126
126
  if (!cfg) return;
127
127
  const teams = cfg.teams ?? {};
128
128
  const team = selectMSTeamsPolicyEntry(teams, params.groupSpace);
@@ -229,8 +229,7 @@ function resolveMSTeamsAutoThreadId(params) {
229
229
  //#endregion
230
230
  //#region extensions/msteams/src/approval-native.ts
231
231
  function isMSTeamsApprovalTransportEnabled(params) {
232
- if (params.accountId && (0, openclaw_plugin_sdk_account_id.normalizeAccountId)(params.accountId) !== openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID) return false;
233
- const account = require_channel_setup.resolveMSTeamsAccount(params.cfg);
232
+ const account = require_resolve_allowlist.resolveMSTeamsAccount(params);
234
233
  return account.enabled && account.configured && account.tokenStatus === "available";
235
234
  }
236
235
  const msTeamsMessagingTargetResolvers = (0, openclaw_plugin_sdk_approval_native_runtime.createNativeApprovalMessagingTargetResolvers)({
@@ -254,12 +253,12 @@ const msTeamsApprovalTargetResolvers = {
254
253
  } : null;
255
254
  }
256
255
  };
257
- const msTeamsApprovalRouteGates = (0, openclaw_plugin_sdk_approval_native_runtime.createNativeApprovalChannelRouteGates)({
256
+ const msTeamsApprovalRouteGates = (0, openclaw_plugin_sdk_approval_native_runtime.createNativeApprovalChannelRouteGatesAsync)({
258
257
  channel: "msteams",
259
258
  defaultForwardingMode: "session",
260
259
  isTransportEnabled: isMSTeamsApprovalTransportEnabled,
261
260
  listAccountIds: require_channel_setup.msteamsConfigAdapter.listAccountIds,
262
- resolveDefaultAccountId: () => openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID,
261
+ resolveDefaultAccountId: require_resolve_allowlist.resolveDefaultMSTeamsAccountId,
263
262
  normalizeForwardTarget: msTeamsApprovalTargetResolvers.normalizeForwardTarget,
264
263
  resolveTurnSourceTarget: msTeamsApprovalTargetResolvers.resolveTurnSourceTarget
265
264
  });
@@ -269,8 +268,8 @@ function isMSTeamsNativeApprovalClientEnabled(params) {
269
268
  nativeSessionOnly: true
270
269
  }) && require_thread_session.getMSTeamsApprovalApprovers(params).length > 0;
271
270
  }
272
- function shouldHandleMSTeamsNativeApprovalRequest(params) {
273
- return msTeamsApprovalRouteGates.shouldHandleApprovalRequest(params) && require_thread_session.getMSTeamsApprovalApprovers(params).length > 0 && Boolean(msTeamsApprovalTargetResolvers.resolveTurnSourceTarget(params.request));
271
+ async function shouldHandleMSTeamsNativeApprovalRequest(params) {
272
+ return await msTeamsApprovalRouteGates.shouldHandleApprovalRequest(params) && require_thread_session.getMSTeamsApprovalApprovers(params).length > 0 && Boolean(msTeamsApprovalTargetResolvers.resolveTurnSourceTarget(params.request));
274
273
  }
275
274
  function shouldSuppressLocalMSTeamsExecApprovalPrompt(params) {
276
275
  return (0, openclaw_plugin_sdk_approval_native_runtime.shouldSuppressLocalNativeExecApprovalPrompt)({
@@ -278,14 +277,14 @@ function shouldSuppressLocalMSTeamsExecApprovalPrompt(params) {
278
277
  isNativeDeliveryEnabled: isMSTeamsNativeApprovalClientEnabled
279
278
  });
280
279
  }
281
- const resolveMSTeamsOriginTarget = (0, openclaw_plugin_sdk_approval_native_runtime.createChannelNativeOriginTargetResolver)({
280
+ const resolveMSTeamsOriginTarget = (0, openclaw_plugin_sdk_approval_native_runtime.createChannelNativeOriginTargetResolverAsync)({
282
281
  channel: "msteams",
283
282
  shouldHandleRequest: shouldHandleMSTeamsNativeApprovalRequest,
284
283
  resolveTurnSourceTarget: msTeamsApprovalTargetResolvers.resolveTurnSourceTarget,
285
284
  resolveSessionTarget: msTeamsApprovalTargetResolvers.resolveSessionTarget,
286
285
  normalizeTarget: msTeamsApprovalTargetResolvers.normalizeTarget
287
286
  });
288
- const msTeamsLazyApprovalNativeRuntime = (0, openclaw_plugin_sdk_approval_handler_adapter_runtime.createLazyChannelApprovalNativeRuntimeAdapter)({
287
+ const msTeamsLazyApprovalNativeRuntime = (0, openclaw_plugin_sdk_approval_handler_adapter_runtime.createLazyChannelApprovalNativeRuntimeAdapterAsync)({
289
288
  capabilityBoundary: true,
290
289
  eventKinds: [
291
290
  "exec",
@@ -303,11 +302,11 @@ const msTeamsLazyApprovalNativeRuntime = (0, openclaw_plugin_sdk_approval_handle
303
302
  request
304
303
  }),
305
304
  load: async () => {
306
- const { msTeamsApprovalNativeRuntime } = await Promise.resolve().then(() => require("./approval-handler.runtime-bUN9icMr.cjs"));
305
+ const { msTeamsApprovalNativeRuntime } = await Promise.resolve().then(() => require("./approval-handler.runtime-DccVf5AY.cjs"));
307
306
  return msTeamsApprovalNativeRuntime;
308
307
  }
309
308
  });
310
- const resolveMSTeamsApproverDmTargets = (0, openclaw_plugin_sdk_approval_native_runtime.createChannelApproverDmTargetResolver)({
309
+ const resolveMSTeamsApproverDmTargets = (0, openclaw_plugin_sdk_approval_native_runtime.createChannelApproverDmTargetResolverAsync)({
311
310
  shouldHandleRequest: shouldHandleMSTeamsNativeApprovalRequest,
312
311
  resolveApprovers: require_thread_session.getMSTeamsApprovalApprovers,
313
312
  mapApprover: (approver, params) => ({
@@ -316,7 +315,7 @@ const resolveMSTeamsApproverDmTargets = (0, openclaw_plugin_sdk_approval_native_
316
315
  })
317
316
  });
318
317
  const msTeamsApprovalCapability = {
319
- ...(0, openclaw_plugin_sdk_approval_delivery_runtime.createApproverRestrictedNativeApprovalCapability)({
318
+ ...(0, openclaw_plugin_sdk_approval_delivery_runtime.createApproverRestrictedNativeApprovalCapabilityAsync)({
320
319
  channel: "msteams",
321
320
  channelLabel: "Microsoft Teams",
322
321
  describeExecApprovalSetup: () => "Approve it from the Web UI for now. Microsoft Teams supports native approvals when the bot is configured. Configure `channels.msteams.allowFrom` or `channels.msteams.defaultTo` with Microsoft Entra object ID approvers.",
@@ -339,17 +338,52 @@ const msTeamsApprovalCapability = {
339
338
  action: "approve",
340
339
  approvalKind: "plugin"
341
340
  })?.authorized ?? false,
342
- isNativeDeliveryEnabled: isMSTeamsNativeApprovalClientEnabled,
341
+ isNativeDeliveryEnabled: async (params) => isMSTeamsNativeApprovalClientEnabled(params),
343
342
  resolveNativeDeliveryMode: () => "channel",
344
343
  requireMatchingTurnSourceChannel: true,
345
344
  resolveSuppressionAccountId: ({ target, request }) => (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(target.accountId) ?? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(request.request.turnSourceAccountId),
346
345
  resolveOriginTarget: resolveMSTeamsOriginTarget,
347
346
  resolveApproverDmTargets: resolveMSTeamsApproverDmTargets,
348
- nativeRuntime: msTeamsLazyApprovalNativeRuntime
347
+ nativeRuntimeAsync: msTeamsLazyApprovalNativeRuntime
349
348
  }),
350
- authorizeActorAction: (params) => require_thread_session.msTeamsApprovalAuth.authorizeActorAction?.(params)
349
+ authorizeActorActionAsync: async (params) => require_thread_session.msTeamsApprovalAuth.authorizeActorAction?.(params)
351
350
  };
352
351
  //#endregion
352
+ //#region extensions/msteams/src/channel-message-tool.ts
353
+ function describeMSTeamsMessageTool({ cfg, accountId }) {
354
+ const account = require_resolve_allowlist.resolveMSTeamsAccount({
355
+ cfg,
356
+ accountId
357
+ });
358
+ const enabled = account.enabled && account.configured && account.tokenStatus === "available";
359
+ return {
360
+ actions: enabled ? [
361
+ "upload-file",
362
+ "poll",
363
+ "edit",
364
+ "delete",
365
+ "pin",
366
+ "unpin",
367
+ "list-pins",
368
+ "read",
369
+ "react",
370
+ "reactions",
371
+ "search",
372
+ "member-info",
373
+ "channel-list",
374
+ "channel-info",
375
+ "addParticipant",
376
+ "removeParticipant",
377
+ "renameGroup"
378
+ ] : [],
379
+ capabilities: enabled ? ["presentation"] : [],
380
+ schema: enabled ? {
381
+ actions: ["unpin"],
382
+ properties: { pinnedMessageId: typebox.Type.Optional(typebox.Type.String({ description: "Pinned message resource ID for unpin (from pin or list-pins, not the chat message ID)." })) }
383
+ } : null
384
+ };
385
+ }
386
+ //#endregion
353
387
  //#region src/gateway/gateway-http-route-contracts.ts
354
388
  const GATEWAY_PROBE_ROUTES = /* @__PURE__ */ new Map([
355
389
  ["/health", "live"],
@@ -482,18 +516,39 @@ var gateway_config_runtime_exports = /* @__PURE__ */ require_rolldown_runtime.__
482
516
  require_rolldown_runtime.__reExport(gateway_config_runtime_exports, require("openclaw/plugin-sdk/gateway-config-runtime"));
483
517
  //#endregion
484
518
  //#region extensions/msteams/src/webhook-route.ts
519
+ function resolveMSTeamsWebhookCollisionIssue(cfg) {
520
+ const owners = /* @__PURE__ */ new Map();
521
+ for (const accountId of require_resolve_allowlist.listMSTeamsAccountIds(cfg)) {
522
+ const account = require_resolve_allowlist.resolveMSTeamsAccountConfig(cfg, accountId);
523
+ if (account.enabled === false) continue;
524
+ const path = account.webhook?.path || "/api/messages";
525
+ const paths = accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID && path !== "/api/messages" ? [path, "/api/messages"] : [path];
526
+ for (const routePath of paths) {
527
+ const canonical = resolvePluginRoutePathContext(routePath).canonicalPath;
528
+ const owner = owners.get(canonical);
529
+ if (owner && owner !== accountId) return "Microsoft Teams webhook path " + routePath + " is shared by accounts " + owner + " and " + accountId + ". Configure distinct webhook.path values.";
530
+ owners.set(canonical, accountId);
531
+ }
532
+ }
533
+ }
485
534
  function resolveMSTeamsLegacyWebhook(config) {
486
535
  return config?.legacyWebhook || void 0;
487
536
  }
488
- function resolveMSTeamsWebhookPathIssue({ cfg, env }) {
489
- const channel = cfg.channels?.msteams;
537
+ function resolveMSTeamsLegacyWebhookConfigPath(cfg, accountId) {
538
+ const accountKey = require_resolve_allowlist.resolveMSTeamsAccountEntryKey(cfg.channels?.msteams?.accounts, accountId);
539
+ return accountKey && cfg.channels?.msteams?.accounts?.[accountKey]?.legacyWebhook ? `${require_resolve_allowlist.resolveMSTeamsAccountConfigPath(cfg, accountId)}.legacyWebhook` : "channels.msteams.legacyWebhook";
540
+ }
541
+ function resolveMSTeamsWebhookPathIssue({ cfg, env, accountId = openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID, accountConfig = require_resolve_allowlist.resolveMSTeamsAccountConfig(cfg, accountId) }) {
542
+ const channel = accountConfig;
490
543
  const path = channel?.webhook?.path || "/api/messages";
491
544
  const legacy = resolveMSTeamsLegacyWebhook(channel);
492
545
  const pathname = URL.parse(path, "http://localhost")?.pathname ?? path;
493
546
  const probe = classifyGatewayProbePath(pathname);
494
547
  const reason = isProtectedPluginRoutePathFromContext(resolvePluginRoutePathContext(pathname)) ? "requires Gateway authentication on the main HTTP listener" : probe !== "namespace" && probe !== "outside" ? "is reserved for Gateway checks" : /[:*{}\\]/.test(path) ? "uses Express pattern syntax that requires the compatibility listener" : void 0;
495
548
  if (!reason) return;
496
- return `Microsoft Teams webhook path ${path} ${reason}. Set channels.msteams.webhook.path to /api/messages and update the Azure Bot messaging endpoint or reverse-proxy upstream to Gateway port ${(0, gateway_config_runtime_exports.resolveGatewayPort)(cfg, env)}/api/messages; verify delivery before removing channels.msteams.legacyWebhook.` + (legacy ? ` Compatibility port ${legacy.port} continues serving the current path.` : " The compatibility listener is disabled, so this path cannot receive Teams callbacks.");
549
+ const configPath = require_resolve_allowlist.resolveMSTeamsAccountConfigPath(cfg, accountId);
550
+ const recoveryPath = accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID ? "/api/messages" : `/api/messages/${accountId}`;
551
+ return `Microsoft Teams webhook path ${path} ${reason}. Set ${configPath}.webhook.path to ${recoveryPath} and update the Azure Bot messaging endpoint or reverse-proxy upstream to Gateway port ${(0, gateway_config_runtime_exports.resolveGatewayPort)(cfg, env)}${recoveryPath}.` + (legacy ? ` Compatibility port ${legacy.port} continues serving the current path; verify delivery before removing ${resolveMSTeamsLegacyWebhookConfigPath(cfg, accountId)}.` : " The compatibility listener is disabled, so this path cannot receive Teams callbacks.");
497
552
  }
498
553
  //#endregion
499
554
  //#region extensions/msteams/src/doctor.ts
@@ -513,22 +568,31 @@ function runMSTeamsWebhookDoctorSequence({ cfg, env }) {
513
568
  warningNotes: [],
514
569
  infoNotes: []
515
570
  };
516
- const pathIssue = resolveMSTeamsWebhookPathIssue({
517
- cfg,
518
- env
519
- });
520
- if (pathIssue) return {
521
- changeNotes: [],
522
- warningNotes: [pathIssue],
523
- infoNotes: []
524
- };
525
- const path = channel.webhook?.path || "/api/messages";
571
+ const warningNotes = [];
572
+ const infoNotes = [];
526
573
  const port = (0, gateway_config_runtime_exports.resolveGatewayPort)(cfg, env);
527
- const legacy = resolveMSTeamsLegacyWebhook(channel);
574
+ for (const accountId of require_resolve_allowlist.listMSTeamsAccountIds(cfg)) {
575
+ const accountConfig = require_resolve_allowlist.resolveMSTeamsAccountConfig(cfg, accountId);
576
+ if (accountConfig.enabled === false) continue;
577
+ const pathIssue = resolveMSTeamsWebhookPathIssue({
578
+ cfg,
579
+ env,
580
+ accountId,
581
+ accountConfig
582
+ });
583
+ if (pathIssue) {
584
+ warningNotes.push(pathIssue);
585
+ continue;
586
+ }
587
+ const path = accountConfig.webhook?.path || "/api/messages";
588
+ const legacy = resolveMSTeamsLegacyWebhook(accountConfig);
589
+ const label = accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID ? "Microsoft Teams" : `Microsoft Teams (${accountId})`;
590
+ infoNotes.push(legacy ? `${label}: compatibility port ${legacy.port} continues forwarding to Gateway route ${path}. To use only the Gateway listener, update the Azure Bot messaging endpoint or reverse-proxy upstream to Gateway port ${port}${path}, verify delivery, then remove the ${resolveMSTeamsLegacyWebhookConfigPath(cfg, accountId)} pin to close the old port.` : `${label} webhooks use Gateway port ${port}${path}; no compatibility listener is configured. Point the Azure Bot messaging endpoint or reverse-proxy upstream to this route.`);
591
+ }
528
592
  return {
529
593
  changeNotes: [],
530
- warningNotes: [],
531
- infoNotes: [legacy ? `Microsoft Teams: compatibility port ${legacy.port} continues forwarding to Gateway route ${path}. To use only the Gateway listener, update the Azure Bot messaging endpoint or reverse-proxy upstream to Gateway port ${port}${path}, verify delivery, then remove the channels.msteams.legacyWebhook pin to close the old port.` : `Microsoft Teams webhooks use Gateway port ${port}${path}; no compatibility listener is configured. Point the Azure Bot messaging endpoint or reverse-proxy upstream to this route.`]
594
+ warningNotes,
595
+ infoNotes
532
596
  };
533
597
  }
534
598
  const msteamsDoctor = {
@@ -678,6 +742,16 @@ function sameAccount(ctx) {
678
742
  const requester = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.requesterAccountId);
679
743
  return requester !== void 0 && requester === requested;
680
744
  }
745
+ function resolveReadPolicyAccountId(cfg, ctx) {
746
+ return (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx?.accountId) ?? require_resolve_allowlist.resolveDefaultMSTeamsAccountId(cfg);
747
+ }
748
+ function resolveReadPolicyConfig(cfg, accountId) {
749
+ return require_resolve_allowlist.withAccountScopedMSTeamsConfig({
750
+ cfg,
751
+ accountId,
752
+ accountConfig: require_resolve_allowlist.resolveMSTeamsAccountConfig(cfg, accountId)
753
+ });
754
+ }
681
755
  function isCurrentMSTeamsReadTarget(params) {
682
756
  if ((0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(params.ctx.toolContext?.currentChannelProvider)?.toLowerCase() !== "msteams" || !sameAccount(params.ctx)) return false;
683
757
  const candidates = [
@@ -694,7 +768,7 @@ function normalizeUserTarget(target) {
694
768
  function isStableUserId(value) {
695
769
  return /^[0-9a-f-]{16,}$/i.test(value);
696
770
  }
697
- async function resolveDmTarget(cfg, target, directOperator = false) {
771
+ async function resolveDmTarget(cfg, accountId, target, directOperator = false) {
698
772
  const teams = cfg.channels?.msteams;
699
773
  if (teams?.dmPolicy === "disabled") return;
700
774
  const userId = normalizeUserTarget(target);
@@ -706,6 +780,7 @@ async function resolveDmTarget(cfg, target, directOperator = false) {
706
780
  try {
707
781
  const [resolvedTarget, ...resolvedEntries] = await require_resolve_allowlist.resolveMSTeamsUserAllowlist({
708
782
  cfg,
783
+ accountId,
709
784
  entries: [userId, ...normalizedEntries.filter((entry) => entry !== "*")]
710
785
  });
711
786
  if (!resolvedTarget?.resolved || !resolvedTarget.id) return;
@@ -735,24 +810,25 @@ function hasMutableChannelConfig(cfg) {
735
810
  return Object.keys(teamConfig?.channels ?? {}).some((channelKey) => channelKey !== "*" && !isStableChannelKey(channelKey));
736
811
  });
737
812
  }
738
- async function resolveConfiguredBotFrameworkTeamKey(cfg, graphTeamId) {
813
+ async function resolveConfiguredBotFrameworkTeamKey(cfg, accountId, graphTeamId) {
739
814
  const configuredTeams = cfg.channels?.msteams?.teams;
740
815
  if (!configuredTeams) return;
741
816
  const stableConfiguredKeys = Object.keys(configuredTeams).filter((teamKey) => teamKey !== "*" && /^19:.+@thread\./i.test(teamKey));
742
817
  if (stableConfiguredKeys.length === 0) return;
743
- const token = await require_resolve_allowlist.resolveGraphToken(cfg);
818
+ const token = await require_resolve_allowlist.resolveGraphToken(cfg, { accountId });
744
819
  const channelResult = await require_resolve_allowlist.listChannelsForTeamWithPageInfo(token, graphTeamId);
745
820
  if (channelResult.truncated) return;
746
821
  const channelIds = new Set(channelResult.items.map((channel) => channel.id?.trim()).filter((channelId) => Boolean(channelId)));
747
822
  const matches = stableConfiguredKeys.filter((teamKey) => channelIds.has(teamKey));
748
823
  return matches.length === 1 ? matches[0] : void 0;
749
824
  }
750
- async function resolveStableChannelTarget(cfg, target) {
825
+ async function resolveStableChannelTarget(cfg, accountId, target) {
751
826
  if (isStableGraphChannelTarget(target)) return target;
752
827
  if (!(0, openclaw_plugin_sdk_dangerous_name_runtime.isDangerousNameMatchingEnabled)(cfg.channels?.msteams)) return;
753
828
  try {
754
829
  const [resolved] = await require_resolve_allowlist.resolveMSTeamsChannelAllowlist({
755
830
  cfg,
831
+ accountId,
756
832
  entries: [target]
757
833
  });
758
834
  return resolved?.resolved && resolved.graphTeamId && resolved.channelId ? `${resolved.graphTeamId}/${resolved.channelId}` : void 0;
@@ -760,7 +836,7 @@ async function resolveStableChannelTarget(cfg, target) {
760
836
  return;
761
837
  }
762
838
  }
763
- async function resolveAllowedChannelTarget(cfg, target) {
839
+ async function resolveAllowedChannelTarget(cfg, accountId, target) {
764
840
  const teams = cfg.channels?.msteams;
765
841
  const groupPolicy = resolveMSTeamsReadGroupPolicy(cfg);
766
842
  if (groupPolicy === "disabled") return;
@@ -774,19 +850,19 @@ async function resolveAllowedChannelTarget(cfg, target) {
774
850
  channelName: channelId,
775
851
  allowNameMatching: (0, openclaw_plugin_sdk_dangerous_name_runtime.isDangerousNameMatchingEnabled)(teams)
776
852
  });
777
- const stableTarget = await resolveStableChannelTarget(cfg, target);
853
+ const stableTarget = await resolveStableChannelTarget(cfg, accountId, target);
778
854
  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\".");
779
855
  if (directRoute.allowed) return stableTarget;
780
856
  if (!stableTarget || !teams?.teams) return;
781
857
  const [stableTeamId, stableChannelId] = stableTarget.split("/", 2);
782
858
  if (!stableTeamId || !stableChannelId) return;
783
- return await isMappedChannelAllowed(cfg, stableTeamId, stableChannelId) ? stableTarget : void 0;
859
+ return await isMappedChannelAllowed(cfg, accountId, stableTeamId, stableChannelId) ? stableTarget : void 0;
784
860
  }
785
- async function isMappedChannelAllowed(cfg, teamId, conversationId) {
861
+ async function isMappedChannelAllowed(cfg, accountId, teamId, conversationId) {
786
862
  const teams = cfg.channels?.msteams;
787
863
  if (!teams?.teams) return false;
788
864
  try {
789
- const botFrameworkTeamKey = await resolveConfiguredBotFrameworkTeamKey(cfg, teamId);
865
+ const botFrameworkTeamKey = await resolveConfiguredBotFrameworkTeamKey(cfg, accountId, teamId);
790
866
  if (botFrameworkTeamKey && resolveMSTeamsRouteConfig({
791
867
  cfg: teams,
792
868
  teamId: botFrameworkTeamKey,
@@ -795,6 +871,7 @@ async function isMappedChannelAllowed(cfg, teamId, conversationId) {
795
871
  if (!hasMutableChannelConfig(cfg)) return false;
796
872
  const resolved = await require_resolve_allowlist.resolveMSTeamsTeamsConfig({
797
873
  cfg,
874
+ accountId,
798
875
  teamIdMode: "graph",
799
876
  teams: teams.teams
800
877
  });
@@ -815,25 +892,32 @@ function bothUnknownScopesAllowed(cfg) {
815
892
  return resolveMSTeamsReadGroupPolicy(cfg) === "open" && (teams?.dmPolicy ?? "pairing") === "open";
816
893
  }
817
894
  async function assertMSTeamsReadTargetAllowed(params) {
895
+ const accountId = resolveReadPolicyAccountId(params.cfg, params.ctx);
896
+ const cfg = resolveReadPolicyConfig(params.cfg, accountId);
818
897
  const target = normalizeTarget(params.target);
819
898
  const isChannel = target.includes("/");
820
899
  const isDm = /^user:/i.test(target);
821
900
  const isChat = require_resolve_allowlist.looksLikeMSTeamsConversationId(target);
822
901
  const current = isCurrentMSTeamsReadTarget({
823
- ctx: params.ctx,
902
+ ctx: {
903
+ ...params.ctx,
904
+ accountId
905
+ },
824
906
  target
825
907
  });
826
908
  const directOperator = params.ctx.conversationReadOrigin === "direct-operator";
827
909
  const currentChatType = params.ctx.toolContext?.currentChatType;
828
- const groupEnabled = resolveMSTeamsReadGroupPolicy(params.cfg) !== "disabled";
829
- const dmEnabled = params.cfg.channels?.msteams?.dmPolicy !== "disabled";
830
- const allowedTarget = directOperator ? isChannel ? groupEnabled ? await resolveStableChannelTarget(params.cfg, target) : void 0 : isDm ? await resolveDmTarget(params.cfg, target, true) : isChat && groupEnabled && dmEnabled ? target : void 0 : current ? (isChannel ? groupEnabled : isDm || currentChatType === "direct" ? dmEnabled : currentChatType === "group" || currentChatType === "channel" ? groupEnabled : groupEnabled && dmEnabled) ? target : void 0 : isChannel ? await resolveAllowedChannelTarget(params.cfg, target) : isDm ? await resolveDmTarget(params.cfg, target) : isChat ? bothUnknownScopesAllowed(params.cfg) ? target : void 0 : false;
910
+ const groupEnabled = resolveMSTeamsReadGroupPolicy(cfg) !== "disabled";
911
+ const dmEnabled = cfg.channels?.msteams?.dmPolicy !== "disabled";
912
+ const allowedTarget = directOperator ? isChannel ? groupEnabled ? await resolveStableChannelTarget(cfg, accountId, target) : void 0 : isDm ? await resolveDmTarget(cfg, accountId, target, true) : isChat && groupEnabled && dmEnabled ? target : void 0 : current ? (isChannel ? groupEnabled : isDm || currentChatType === "direct" ? dmEnabled : currentChatType === "group" || currentChatType === "channel" ? groupEnabled : groupEnabled && dmEnabled) ? target : void 0 : isChannel ? await resolveAllowedChannelTarget(cfg, accountId, target) : isDm ? await resolveDmTarget(cfg, accountId, target) : isChat ? bothUnknownScopesAllowed(cfg) ? target : void 0 : false;
831
913
  if (!allowedTarget) throw new openclaw_plugin_sdk_channel_actions.ToolAuthorizationError("Microsoft Teams read target is not allowed.");
832
914
  return allowedTarget;
833
915
  }
834
916
  async function assertMSTeamsTeamEnumerationAllowed(params) {
835
- const teams = params.cfg.channels?.msteams;
836
- const groupPolicy = resolveMSTeamsReadGroupPolicy(params.cfg);
917
+ const accountId = resolveReadPolicyAccountId(params.cfg, params.ctx);
918
+ const cfg = resolveReadPolicyConfig(params.cfg, accountId);
919
+ const teams = cfg.channels?.msteams;
920
+ const groupPolicy = resolveMSTeamsReadGroupPolicy(cfg);
837
921
  if (groupPolicy === "disabled") throw new openclaw_plugin_sdk_channel_actions.ToolAuthorizationError("Microsoft Teams channel list is not allowed.");
838
922
  const directRoute = resolveMSTeamsRouteConfig({
839
923
  cfg: teams,
@@ -843,12 +927,13 @@ async function assertMSTeamsTeamEnumerationAllowed(params) {
843
927
  allowNameMatching: (0, openclaw_plugin_sdk_dangerous_name_runtime.isDangerousNameMatchingEnabled)(teams)
844
928
  });
845
929
  const stableTeamId = isStableGraphTeamId(params.teamId) ? params.teamId : (0, openclaw_plugin_sdk_dangerous_name_runtime.isDangerousNameMatchingEnabled)(teams) ? (await require_resolve_allowlist.resolveMSTeamsChannelAllowlist({
846
- cfg: params.cfg,
930
+ cfg,
931
+ accountId,
847
932
  entries: [params.teamId]
848
933
  }))[0]?.graphTeamId : void 0;
849
934
  if (!stableTeamId) throw new openclaw_plugin_sdk_channel_actions.ToolAuthorizationError("Microsoft Teams channel list requires access to every channel in the team.");
850
935
  if (params.ctx?.conversationReadOrigin === "direct-operator") return stableTeamId;
851
- if (!((directRoute.allowlistConfigured ? directRoute.allowed : groupPolicy === "open") || await isMappedChannelAllowed(params.cfg, stableTeamId, "__openclaw_all_channels__"))) throw new openclaw_plugin_sdk_channel_actions.ToolAuthorizationError("Microsoft Teams channel list requires access to every channel in the team.");
936
+ if (!((directRoute.allowlistConfigured ? directRoute.allowed : groupPolicy === "open") || await isMappedChannelAllowed(cfg, accountId, stableTeamId, "__openclaw_all_channels__"))) throw new openclaw_plugin_sdk_channel_actions.ToolAuthorizationError("Microsoft Teams channel list requires access to every channel in the team.");
852
937
  return stableTeamId;
853
938
  }
854
939
  //#endregion
@@ -914,18 +999,13 @@ const TEAMS_GRAPH_PERMISSION_HINTS = {
914
999
  "Sites.Read.All": "files (SharePoint)",
915
1000
  "Files.Read.All": "files (OneDrive)"
916
1001
  };
917
- const collectMSTeamsSecurityWarnings = (0, openclaw_plugin_sdk_channel_policy.createAllowlistProviderGroupPolicyWarningCollector)({
918
- providerConfigPresent: (cfg) => cfg.channels?.msteams !== void 0,
919
- resolveGroupPolicy: ({ cfg }) => cfg.channels?.msteams?.groupPolicy,
920
- 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."] : []
921
- });
922
1002
  const collectMSTeamsSecurityFindings = openclaw_plugin_sdk_channel_policy.createConditionalWarningCollector.findings({
923
- collectWarnings: collectMSTeamsSecurityWarnings,
1003
+ collectWarnings: require_channel_setup.collectMSTeamsSecurityWarnings,
924
1004
  checkId: "channels.msteams.groups.open",
925
1005
  severity: "warn",
926
1006
  title: "MS Teams security warning"
927
1007
  });
928
- const loadMSTeamsChannelRuntime = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeNamedExport)(() => Promise.resolve().then(() => require("./channel.runtime-DWRAolil.cjs")), "msTeamsChannelRuntime");
1008
+ const loadMSTeamsChannelRuntime = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeNamedExport)(() => Promise.resolve().then(() => require("./channel.runtime-DzKeQAqd.cjs")), "msTeamsChannelRuntime");
929
1009
  const MSTEAMS_REACTION_TYPES = [
930
1010
  "like",
931
1011
  "heart",
@@ -952,44 +1032,21 @@ function resolveGraphActionTarget(params, currentChannelId, currentGraphChannelI
952
1032
  if (currentGraphTarget) return currentGraphTarget;
953
1033
  return currentChatType === "channel" ? "" : currentChannelTarget ?? "";
954
1034
  }
955
- function resolveMSTeamsActionMessageId(ctx, to, allowCurrentMessageIdFallback = false) {
956
- const messageId = allowCurrentMessageIdFallback && msteamsContextTargetsMatch(to, {
1035
+ function resolveMSTeamsActionMessage(ctx, to, allowCurrentMessageIdFallback = false) {
1036
+ const canUseCurrentMessageId = allowCurrentMessageIdFallback && msteamsContextTargetsMatch(to, {
957
1037
  currentChannelId: ctx.toolContext?.currentChannelId ?? void 0,
958
1038
  currentMessagingTarget: (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.toolContext?.currentGraphChannelId) ?? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.toolContext?.currentMessagingTarget)
959
- }) ? (0, openclaw_plugin_sdk_channel_actions.resolveReactionMessageId)({
1039
+ });
1040
+ const resolved = canUseCurrentMessageId ? (0, openclaw_plugin_sdk_channel_actions.resolveReactionMessageId)({
960
1041
  args: ctx.params,
961
1042
  toolContext: { currentMessageId: ctx.toolContext?.currentMessageId ?? void 0 }
962
1043
  }) : (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.params.messageId) ?? "";
963
- return messageId == null ? "" : String(messageId).trim();
964
- }
965
- function describeMSTeamsMessageTool({ cfg }) {
966
- const account = require_channel_setup.resolveMSTeamsAccount(cfg);
967
- const enabled = account.enabled && account.configured && account.tokenStatus === "available";
1044
+ const messageId = resolved == null ? "" : String(resolved).trim();
1045
+ const currentMessageId = ctx.toolContext?.currentMessageId;
1046
+ const threadRootId = canUseCurrentMessageId && ctx.toolContext?.currentChatType === "channel" && currentMessageId != null && messageId === String(currentMessageId).trim() ? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.toolContext.currentThreadTs) : void 0;
968
1047
  return {
969
- actions: enabled ? [
970
- "upload-file",
971
- "poll",
972
- "edit",
973
- "delete",
974
- "pin",
975
- "unpin",
976
- "list-pins",
977
- "read",
978
- "react",
979
- "reactions",
980
- "search",
981
- "member-info",
982
- "channel-list",
983
- "channel-info",
984
- "addParticipant",
985
- "removeParticipant",
986
- "renameGroup"
987
- ] : [],
988
- capabilities: enabled ? ["presentation"] : [],
989
- schema: enabled ? {
990
- actions: ["unpin"],
991
- properties: { pinnedMessageId: typebox.Type.Optional(typebox.Type.String({ description: "Pinned message resource ID for unpin (from pin or list-pins, not the chat message ID)." })) }
992
- } : null
1048
+ messageId,
1049
+ ...threadRootId ? { threadRootId } : {}
993
1050
  };
994
1051
  }
995
1052
  const msteamsChannelOutbound = {
@@ -1057,7 +1114,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1057
1114
  listGroupsLive: (runtime) => runtime.listMSTeamsDirectoryGroupsLive
1058
1115
  })
1059
1116
  }),
1060
- resolver: { resolveTargets: async ({ cfg, inputs, kind, runtime }) => {
1117
+ resolver: { resolveTargets: async ({ cfg, accountId, inputs, kind, runtime }) => {
1061
1118
  const results = inputs.map((input) => ({
1062
1119
  input,
1063
1120
  resolved: false,
@@ -1065,94 +1122,85 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1065
1122
  name: void 0,
1066
1123
  note: void 0
1067
1124
  }));
1068
- const resolvePending = async (pending, resolveEntries, applyResolvedEntry) => {
1069
- if (pending.length === 0) return;
1070
- try {
1071
- (await resolveEntries(pending.map((entry) => entry.query))).forEach((entry, idx) => {
1072
- const target = results[pending[idx]?.index ?? -1];
1073
- if (!target) return;
1074
- applyResolvedEntry(target, entry);
1075
- });
1076
- } catch (err) {
1077
- runtime.error?.(`msteams resolve failed: ${String(err)}`);
1078
- for (const { index } of pending) results[index].note = "lookup failed";
1125
+ const pending = [];
1126
+ for (const entry of results) {
1127
+ const trimmed = entry.input.trim();
1128
+ if (!trimmed) {
1129
+ entry.note = "empty input";
1130
+ continue;
1079
1131
  }
1080
- };
1081
- if (kind === "user") {
1082
- const pending = [];
1083
- results.forEach((entry, index) => {
1084
- const trimmed = entry.input.trim();
1085
- if (!trimmed) {
1086
- entry.note = "empty input";
1087
- return;
1088
- }
1132
+ if (kind === "user") {
1089
1133
  const cleaned = require_resolve_allowlist.normalizeMSTeamsUserInput(trimmed);
1090
1134
  if (/^[0-9a-fA-F-]{16,}$/.test(cleaned) || cleaned.includes("@")) {
1091
1135
  entry.resolved = true;
1092
1136
  entry.id = cleaned;
1093
- return;
1094
- }
1095
- pending.push({
1137
+ } else pending.push({
1096
1138
  query: cleaned,
1097
- index
1139
+ target: entry
1098
1140
  });
1099
- });
1100
- await resolvePending(pending, (entries) => require_resolve_allowlist.resolveMSTeamsUserAllowlist({
1101
- cfg,
1102
- entries
1103
- }), (target, entry) => {
1104
- target.resolved = entry.resolved;
1105
- target.id = entry.id;
1106
- target.name = entry.name;
1107
- target.note = entry.note;
1108
- });
1109
- return results;
1110
- }
1111
- const pending = [];
1112
- results.forEach((entry, index) => {
1113
- const trimmed = entry.input.trim();
1114
- if (!trimmed) {
1115
- entry.note = "empty input";
1116
- return;
1141
+ continue;
1117
1142
  }
1118
1143
  const conversationId = require_resolve_allowlist.parseMSTeamsConversationId(trimmed);
1119
1144
  if (conversationId !== null) {
1120
1145
  entry.resolved = Boolean(conversationId);
1121
1146
  entry.id = conversationId || void 0;
1122
1147
  entry.note = conversationId ? "conversation id" : "empty conversation id";
1123
- return;
1148
+ continue;
1124
1149
  }
1125
1150
  const parsed = require_resolve_allowlist.parseMSTeamsTeamChannelInput(trimmed);
1126
1151
  if (!parsed.team) {
1127
1152
  entry.note = "missing team";
1128
- return;
1153
+ continue;
1129
1154
  }
1130
1155
  const query = parsed.channel ? `${parsed.team}/${parsed.channel}` : parsed.team;
1131
1156
  pending.push({
1132
1157
  query,
1133
- index
1158
+ target: entry
1134
1159
  });
1135
- });
1136
- await resolvePending(pending, (entries) => require_resolve_allowlist.resolveMSTeamsChannelAllowlist({
1137
- cfg,
1138
- entries
1139
- }), (target, entry) => {
1140
- if (!entry.resolved || !entry.teamId) {
1141
- target.resolved = false;
1142
- target.note = entry.note;
1143
- return;
1144
- }
1145
- target.resolved = true;
1146
- if (entry.channelId) {
1147
- target.id = `${entry.teamId}/${entry.channelId}`;
1148
- target.name = entry.channelName && entry.teamName ? `${entry.teamName}/${entry.channelName}` : entry.channelName ?? entry.teamName;
1149
- } else {
1150
- target.id = entry.teamId;
1151
- target.name = entry.teamName;
1152
- target.note = "team id";
1153
- }
1154
- if (entry.note) target.note = entry.note;
1155
- });
1160
+ }
1161
+ if (pending.length === 0) return results;
1162
+ const entries = pending.map((entry) => entry.query);
1163
+ try {
1164
+ if (kind === "user") (await require_resolve_allowlist.resolveMSTeamsUserAllowlist({
1165
+ cfg,
1166
+ accountId,
1167
+ entries
1168
+ })).forEach((entry, index) => {
1169
+ const target = pending[index]?.target;
1170
+ if (target) {
1171
+ target.resolved = entry.resolved;
1172
+ target.id = entry.id;
1173
+ target.name = entry.name;
1174
+ target.note = entry.note;
1175
+ }
1176
+ });
1177
+ else (await require_resolve_allowlist.resolveMSTeamsChannelAllowlist({
1178
+ cfg,
1179
+ accountId,
1180
+ entries
1181
+ })).forEach((entry, index) => {
1182
+ const target = pending[index]?.target;
1183
+ if (!target) return;
1184
+ if (!entry.resolved || !entry.teamId) {
1185
+ target.resolved = false;
1186
+ target.note = entry.note;
1187
+ return;
1188
+ }
1189
+ target.resolved = true;
1190
+ if (entry.channelId) {
1191
+ target.id = `${entry.teamId}/${entry.channelId}`;
1192
+ target.name = entry.channelName && entry.teamName ? `${entry.teamName}/${entry.channelName}` : entry.channelName ?? entry.teamName;
1193
+ } else {
1194
+ target.id = entry.teamId;
1195
+ target.name = entry.teamName;
1196
+ target.note = "team id";
1197
+ }
1198
+ if (entry.note) target.note = entry.note;
1199
+ });
1200
+ } catch (err) {
1201
+ runtime.error?.(`msteams resolve failed: ${String(err)}`);
1202
+ for (const { target } of pending) target.note = "lookup failed";
1203
+ }
1156
1204
  return results;
1157
1205
  } },
1158
1206
  actions: {
@@ -1174,9 +1222,15 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1174
1222
  const authError = requireMSTeamsGroupManagementAuthorization(ctx);
1175
1223
  if (authError) return authError;
1176
1224
  }
1225
+ const accountId = ctx.accountId ?? require_resolve_allowlist.resolveDefaultMSTeamsAccountId(ctx.cfg);
1226
+ const actionAccountId = ctx.accountId ?? (accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID ? void 0 : accountId);
1227
+ const actionContext = {
1228
+ ...ctx,
1229
+ accountId
1230
+ };
1177
1231
  const authorizeActionTarget = (target) => assertMSTeamsReadTargetAllowed({
1178
1232
  cfg: ctx.cfg,
1179
- ctx,
1233
+ ctx: actionContext,
1180
1234
  target
1181
1235
  });
1182
1236
  const presentation = ctx.action === "send" ? (0, openclaw_plugin_sdk_interactive_runtime.normalizeMessagePresentation)(ctx.params.presentation) : void 0;
@@ -1190,6 +1244,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1190
1244
  const { sendAdaptiveCardMSTeams } = await loadMSTeamsChannelRuntime();
1191
1245
  const result = await sendAdaptiveCardMSTeams({
1192
1246
  cfg: ctx.cfg,
1247
+ accountId: actionAccountId,
1193
1248
  to,
1194
1249
  card,
1195
1250
  assertDirectAdapterHandoff: ctx.assertDirectAdapterHandoff,
@@ -1210,6 +1265,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1210
1265
  const { sendMessageMSTeams } = await loadMSTeamsChannelRuntime();
1211
1266
  const result = await sendMessageMSTeams({
1212
1267
  cfg: ctx.cfg,
1268
+ accountId: actionAccountId,
1213
1269
  to,
1214
1270
  text: resolveActionContent(ctx.params),
1215
1271
  mediaUrl,
@@ -1240,6 +1296,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1240
1296
  const runtime = await loadMSTeamsChannelRuntime();
1241
1297
  const params = {
1242
1298
  cfg: ctx.cfg,
1299
+ accountId: actionAccountId,
1243
1300
  to,
1244
1301
  activityId: messageId
1245
1302
  };
@@ -1254,7 +1311,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1254
1311
  } : ctx.params, ctx.toolContext?.currentChannelId, (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.toolContext?.currentGraphChannelId) ?? (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(ctx.toolContext?.currentMessagingTarget), ctx.toolContext?.currentChatType);
1255
1312
  if (ctx.action === "read" || ctx.action === "pin" || ctx.action === "reactions") {
1256
1313
  const action = ctx.action;
1257
- const messageId = resolveMSTeamsActionMessageId(ctx, graphTo, action === "reactions");
1314
+ const { messageId, threadRootId } = resolveMSTeamsActionMessage(ctx, graphTo, action === "reactions");
1258
1315
  if (!graphTo || !messageId) return actionError(`${{
1259
1316
  read: "Read",
1260
1317
  pin: "Pin",
@@ -1264,8 +1321,10 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1264
1321
  const runtime = await loadMSTeamsChannelRuntime();
1265
1322
  const params = {
1266
1323
  cfg: ctx.cfg,
1324
+ accountId: actionAccountId,
1267
1325
  to,
1268
- messageId
1326
+ messageId,
1327
+ threadRootId
1269
1328
  };
1270
1329
  if (action === "read") return jsonMSTeamsOkActionResult(action, { message: await runtime.getMessageMSTeams(params) });
1271
1330
  if (action === "pin") return jsonMSTeamsActionResult(action, await runtime.pinMessageMSTeams(params));
@@ -1278,6 +1337,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1278
1337
  const { unpinMessageMSTeams } = await loadMSTeamsChannelRuntime();
1279
1338
  return jsonMSTeamsActionResult("unpin", await unpinMessageMSTeams({
1280
1339
  cfg: ctx.cfg,
1340
+ accountId: actionAccountId,
1281
1341
  to,
1282
1342
  pinnedMessageId
1283
1343
  }));
@@ -1288,11 +1348,12 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1288
1348
  const { listPinsMSTeams } = await loadMSTeamsChannelRuntime();
1289
1349
  return jsonMSTeamsOkActionResult("list-pins", await listPinsMSTeams({
1290
1350
  cfg: ctx.cfg,
1351
+ accountId: actionAccountId,
1291
1352
  to
1292
1353
  }));
1293
1354
  }
1294
1355
  if (ctx.action === "react") {
1295
- const messageId = resolveMSTeamsActionMessageId(ctx, graphTo, true);
1356
+ const { messageId, threadRootId } = resolveMSTeamsActionMessage(ctx, graphTo, true);
1296
1357
  if (!graphTo || !messageId) return actionError("React requires a target (to) and messageId.");
1297
1358
  const emoji = typeof ctx.params.emoji === "string" ? ctx.params.emoji.trim() : "";
1298
1359
  const remove = typeof ctx.params.remove === "boolean" ? ctx.params.remove : false;
@@ -1307,8 +1368,10 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1307
1368
  const runtime = await loadMSTeamsChannelRuntime();
1308
1369
  const result = await (remove ? runtime.unreactMessageMSTeams : runtime.reactMessageMSTeams)({
1309
1370
  cfg: ctx.cfg,
1371
+ accountId: actionAccountId,
1310
1372
  to,
1311
1373
  messageId,
1374
+ threadRootId,
1312
1375
  reactionType: emoji
1313
1376
  });
1314
1377
  return jsonMSTeamsActionResult("react", {
@@ -1327,6 +1390,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1327
1390
  const { searchMessagesMSTeams } = await loadMSTeamsChannelRuntime();
1328
1391
  return jsonMSTeamsOkActionResult("search", await searchMessagesMSTeams({
1329
1392
  cfg: ctx.cfg,
1393
+ accountId: actionAccountId,
1330
1394
  to,
1331
1395
  query,
1332
1396
  from: from || void 0,
@@ -1339,12 +1403,13 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1339
1403
  if (!graphTo) return actionError("member-info requires a target (to).");
1340
1404
  const to = await authorizeActionTarget(graphTo);
1341
1405
  const currentRequesterId = isCurrentMSTeamsReadTarget({
1342
- ctx,
1406
+ ctx: actionContext,
1343
1407
  target: to
1344
1408
  }) ? ctx.requesterSenderId : void 0;
1345
1409
  const { getMemberInfoMSTeams } = await loadMSTeamsChannelRuntime();
1346
1410
  return jsonMSTeamsOkActionResult("member-info", await getMemberInfoMSTeams({
1347
1411
  cfg: ctx.cfg,
1412
+ accountId: actionAccountId,
1348
1413
  to,
1349
1414
  userId,
1350
1415
  currentRequesterId
@@ -1355,12 +1420,13 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1355
1420
  if (!teamId) return actionError("channel-list requires a teamId.");
1356
1421
  const graphTeamId = await assertMSTeamsTeamEnumerationAllowed({
1357
1422
  cfg: ctx.cfg,
1358
- ctx,
1423
+ ctx: actionContext,
1359
1424
  teamId
1360
1425
  });
1361
1426
  const { listChannelsMSTeams } = await loadMSTeamsChannelRuntime();
1362
1427
  return jsonMSTeamsOkActionResult("channel-list", await listChannelsMSTeams({
1363
1428
  cfg: ctx.cfg,
1429
+ accountId: actionAccountId,
1364
1430
  teamId: graphTeamId
1365
1431
  }));
1366
1432
  }
@@ -1373,6 +1439,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1373
1439
  const { getChannelInfoMSTeams } = await loadMSTeamsChannelRuntime();
1374
1440
  return jsonMSTeamsOkActionResult("channel-info", { channelInfo: (await getChannelInfoMSTeams({
1375
1441
  cfg: ctx.cfg,
1442
+ accountId: actionAccountId,
1376
1443
  teamId: graphTeamId,
1377
1444
  channelId: graphChannelId
1378
1445
  })).channel });
@@ -1387,6 +1454,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1387
1454
  const runtime = await loadMSTeamsChannelRuntime();
1388
1455
  const params = {
1389
1456
  cfg: ctx.cfg,
1457
+ accountId: actionAccountId,
1390
1458
  to,
1391
1459
  userId
1392
1460
  };
@@ -1403,6 +1471,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1403
1471
  const { renameGroupMSTeams } = await loadMSTeamsChannelRuntime();
1404
1472
  return jsonMSTeamsOkActionResult("renameGroup", await renameGroupMSTeams({
1405
1473
  cfg: ctx.cfg,
1474
+ accountId: actionAccountId,
1406
1475
  to,
1407
1476
  name
1408
1477
  }));
@@ -1413,7 +1482,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1413
1482
  status: (0, openclaw_plugin_sdk_status_helpers.createComputedAccountStatusAdapter)({
1414
1483
  defaultRuntime: (0, openclaw_plugin_sdk_channel_status.createDefaultChannelRuntimeState)(openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID, { port: null }),
1415
1484
  buildChannelSummary: ({ snapshot }) => (0, openclaw_plugin_sdk_channel_status.buildProbeChannelStatusSummary)(snapshot, { port: snapshot.port ?? null }),
1416
- probeAccount: async ({ cfg }) => await (await loadMSTeamsChannelRuntime()).probeMSTeams(cfg.channels?.msteams),
1485
+ probeAccount: async ({ account }) => await (await loadMSTeamsChannelRuntime()).probeMSTeams(account.config, { accountId: account.accountId }),
1417
1486
  formatCapabilitiesProbe: ({ probe }) => {
1418
1487
  const lines = [];
1419
1488
  const appId = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(probe?.appId);
@@ -1445,41 +1514,52 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1445
1514
  })
1446
1515
  }),
1447
1516
  gateway: { startAccount: async (ctx) => {
1448
- const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./monitor-C9x_CJhY.cjs"));
1449
- const webhookPath = ctx.cfg.channels?.msteams?.webhook?.path || "/api/messages";
1517
+ const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./monitor-CzRI-Hsc.cjs"));
1518
+ const account = require_resolve_allowlist.resolveMSTeamsAccount({
1519
+ cfg: ctx.cfg,
1520
+ accountId: ctx.accountId
1521
+ });
1522
+ const accountId = account.accountId;
1523
+ const webhookPath = account.config.webhook?.path || "/api/messages";
1450
1524
  const statusSink = (0, openclaw_plugin_sdk_channel_outbound.createAccountStatusSink)({
1451
- accountId: ctx.accountId,
1525
+ accountId,
1452
1526
  setStatus: ctx.setStatus
1453
1527
  });
1454
- ctx.log?.info(`starting provider (Gateway route ${webhookPath})`);
1528
+ ctx.log?.info("starting provider account " + accountId + " (Gateway route " + webhookPath + ")");
1455
1529
  if (isMSTeamsNativeApprovalClientEnabled({
1456
1530
  cfg: ctx.cfg,
1457
- accountId: ctx.accountId
1531
+ accountId
1458
1532
  })) (0, openclaw_plugin_sdk_channel_runtime_context.registerChannelRuntimeContext)({
1459
1533
  channelRuntime: ctx.channelRuntime,
1460
1534
  channelId: "msteams",
1461
- accountId: ctx.accountId,
1535
+ accountId,
1462
1536
  capability: openclaw_plugin_sdk_approval_handler_adapter_runtime.CHANNEL_APPROVAL_NATIVE_RUNTIME_CONTEXT_CAPABILITY,
1463
1537
  context: {},
1464
1538
  abortSignal: ctx.abortSignal
1465
1539
  });
1466
1540
  return monitorMSTeamsProvider({
1467
1541
  cfg: ctx.cfg,
1542
+ accountId,
1543
+ msteamsCfg: account.config,
1468
1544
  runtime: ctx.runtime,
1469
1545
  abortSignal: ctx.abortSignal,
1470
1546
  statusSink
1471
1547
  });
1472
1548
  } }
1473
1549
  },
1474
- security: { collectWarnings: ({ cfg }) => collectMSTeamsSecurityFindings({ cfg }) },
1550
+ security: { collectWarnings: ({ cfg, accountId }) => collectMSTeamsSecurityFindings({
1551
+ cfg,
1552
+ accountId
1553
+ }) },
1475
1554
  pairing: { text: {
1476
1555
  idLabel: "msteamsUserId",
1477
1556
  message: openclaw_plugin_sdk_channel_status.PAIRING_APPROVED_MESSAGE,
1478
1557
  normalizeAllowEntry: (0, openclaw_plugin_sdk_channel_pairing.createPairingPrefixStripper)(/^(msteams|user):/i),
1479
- notify: async ({ cfg, id, message }) => {
1558
+ notify: async ({ cfg, accountId, id, message }) => {
1480
1559
  const { sendMessageMSTeams } = await loadMSTeamsChannelRuntime();
1481
1560
  await sendMessageMSTeams({
1482
1561
  cfg,
1562
+ accountId,
1483
1563
  to: id,
1484
1564
  text: message
1485
1565
  });
@@ -1502,8 +1582,8 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1502
1582
  hasRepliedRef
1503
1583
  };
1504
1584
  },
1505
- resolveAutoThreadId: ({ cfg, to, toolContext }) => resolveMSTeamsAutoThreadId({
1506
- cfg: cfg.channels?.msteams,
1585
+ resolveAutoThreadId: ({ cfg, accountId, to, toolContext }) => resolveMSTeamsAutoThreadId({
1586
+ cfg: require_resolve_allowlist.resolveMSTeamsAccountConfig(cfg, accountId),
1507
1587
  to,
1508
1588
  toolContext
1509
1589
  })
@@ -1565,6 +1645,12 @@ Object.defineProperty(exports, "resolveMSTeamsRouteConfig", {
1565
1645
  return resolveMSTeamsRouteConfig;
1566
1646
  }
1567
1647
  });
1648
+ Object.defineProperty(exports, "resolveMSTeamsWebhookCollisionIssue", {
1649
+ enumerable: true,
1650
+ get: function() {
1651
+ return resolveMSTeamsWebhookCollisionIssue;
1652
+ }
1653
+ });
1568
1654
  Object.defineProperty(exports, "resolveMSTeamsWebhookPathIssue", {
1569
1655
  enumerable: true,
1570
1656
  get: function() {