@openclaw/msteams 2026.7.2-beta.5 → 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,20 +1,78 @@
1
- const require_delegated_state = require("./delegated-state-DOSCHaAB.cjs");
2
1
  const require_runtime = require("./runtime-gZTAuFux.cjs");
3
2
  require("./runtime-api.cjs");
3
+ const require_delegated_state = require("./delegated-state-DiEz9JIa.cjs");
4
4
  let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime");
5
5
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
6
6
  let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
7
7
  let openclaw_plugin_sdk_ssrf_runtime = require("openclaw/plugin-sdk/ssrf-runtime");
8
+ let openclaw_plugin_sdk_html_entity_runtime = require("openclaw/plugin-sdk/html-entity-runtime");
9
+ let openclaw_plugin_sdk_fetch_runtime = require("openclaw/plugin-sdk/fetch-runtime");
8
10
  let openclaw_plugin_sdk_provider_http = require("openclaw/plugin-sdk/provider-http");
9
11
  let node_buffer = require("node:buffer");
10
12
  let node_dns_promises = require("node:dns/promises");
11
13
  let openclaw_plugin_sdk_ssrf_policy = require("openclaw/plugin-sdk/ssrf-policy");
12
14
  let openclaw_plugin_sdk_number_runtime = require("openclaw/plugin-sdk/number-runtime");
13
15
  let openclaw_plugin_sdk_text_utility_runtime = require("openclaw/plugin-sdk/text-utility-runtime");
14
- let node_fs = require("node:fs");
15
- node_fs = require_delegated_state.__toESM(node_fs, 1);
16
+ let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
17
+ let openclaw_plugin_sdk_secret_file = require("openclaw/plugin-sdk/secret-file");
16
18
  let node_module = require("node:module");
17
19
  let openclaw_plugin_sdk_secret_input = require("openclaw/plugin-sdk/secret-input");
20
+ //#region extensions/msteams/src/inbound.ts
21
+ /**
22
+ * Strip HTML tags, preserving text content.
23
+ */
24
+ function htmlToPlainText(html) {
25
+ return (0, openclaw_plugin_sdk_html_entity_runtime.decodeHtmlEntities)(html.replace(/<[^>]*>/g, " ")).replaceAll("\xA0", " ").replace(/\s+/g, " ").trim();
26
+ }
27
+ /**
28
+ * Extract quote info from MS Teams HTML reply attachments.
29
+ * Teams wraps quoted content in a blockquote with itemtype="http://schema.skype.com/Reply".
30
+ */
31
+ function extractMSTeamsQuoteInfo(attachments) {
32
+ for (const att of attachments) {
33
+ let content = "";
34
+ if (typeof att.content === "string") content = att.content;
35
+ else if (typeof att.content === "object" && att.content !== null) {
36
+ const record = att.content;
37
+ content = typeof record.text === "string" ? record.text : typeof record.body === "string" ? record.body : "";
38
+ }
39
+ if (!content) continue;
40
+ if (!content.includes("http://schema.skype.com/Reply")) continue;
41
+ const senderMatch = /<strong[^>]*itemprop=["']mri["'][^>]*>(.*?)<\/strong>/i.exec(content);
42
+ const sender = senderMatch?.[1] ? htmlToPlainText(senderMatch[1]) : void 0;
43
+ const bodyMatch = /<p[^>]*itemprop=["']copy["'][^>]*>(.*?)<\/p>/is.exec(content) ?? /<p[^>]*itemprop=["']preview["'][^>]*>(.*?)<\/p>/is.exec(content);
44
+ const body = bodyMatch?.[1] ? htmlToPlainText(bodyMatch[1]) : void 0;
45
+ const id = /<blockquote[^>]*\bitemid=["']([^"']+)["'][^>]*>/is.exec(content)?.[1]?.trim() || void 0;
46
+ if (body) return {
47
+ sender: sender ?? "unknown",
48
+ body,
49
+ ...id ? { id } : {}
50
+ };
51
+ }
52
+ }
53
+ function normalizeMSTeamsConversationId(raw) {
54
+ return raw.split(";")[0] ?? raw;
55
+ }
56
+ function extractMSTeamsConversationMessageId(raw) {
57
+ if (!raw) return;
58
+ return (/(?:^|;)messageid=([^;]+)/i.exec(raw)?.[1]?.trim() ?? "") || void 0;
59
+ }
60
+ function parseMSTeamsActivityTimestamp(value) {
61
+ if (!value) return;
62
+ if (value instanceof Date) return value;
63
+ if (typeof value !== "string") return;
64
+ const date = new Date(value);
65
+ return Number.isNaN(date.getTime()) ? void 0 : date;
66
+ }
67
+ function stripMSTeamsMentionTags(text) {
68
+ return text.replace(/<at[^>]*>.*?<\/at>/gi, "").trim();
69
+ }
70
+ function wasMSTeamsBotMentioned(activity) {
71
+ const botId = activity.recipient?.id;
72
+ if (!botId) return false;
73
+ return (activity.entities ?? []).some((e) => e.type === "mention" && e.mentioned?.id === botId);
74
+ }
75
+ //#endregion
18
76
  //#region extensions/msteams/src/request-timeout.ts
19
77
  const MSTEAMS_REQUEST_TIMEOUT_MS = 3e4;
20
78
  const MSTEAMS_SHAREPOINT_UPLOAD_BASE_TIMEOUT_MS = 5 * 6e4;
@@ -58,52 +116,6 @@ async function withMSTeamsAbortableRequestTimeout(params) {
58
116
  }
59
117
  }
60
118
  //#endregion
61
- //#region extensions/msteams/src/response-with-release.ts
62
- const NULL_BODY_STATUSES = /* @__PURE__ */ new Set([
63
- 101,
64
- 204,
65
- 205,
66
- 304
67
- ]);
68
- function responseWithRelease(response, release) {
69
- let released = false;
70
- const releaseOnce = async () => {
71
- if (released) return;
72
- released = true;
73
- await release();
74
- };
75
- if (!response.body || NULL_BODY_STATUSES.has(response.status)) {
76
- releaseOnce();
77
- return response;
78
- }
79
- const reader = response.body.getReader();
80
- const body = new ReadableStream({
81
- async pull(controller) {
82
- try {
83
- const next = await reader.read();
84
- if (next.done) {
85
- controller.close();
86
- await releaseOnce();
87
- return;
88
- }
89
- controller.enqueue(next.value);
90
- } catch (error) {
91
- await releaseOnce();
92
- throw error;
93
- }
94
- },
95
- async cancel(reason) {
96
- reader.cancel(reason).catch(() => void 0);
97
- await releaseOnce();
98
- }
99
- });
100
- return new Response(body, {
101
- status: response.status,
102
- statusText: response.statusText,
103
- headers: response.headers
104
- });
105
- }
106
- //#endregion
107
119
  //#region extensions/msteams/src/attachments/shared.ts
108
120
  const IMAGE_EXT_RE = /\.(avif|bmp|gif|heic|heif|jpe?g|png|tiff?|webp)$/i;
109
121
  const IMG_SRC_RE = /<img[^>]+src=["']([^"']+)["'][^>]*>/gi;
@@ -477,6 +489,9 @@ async function resolveAndValidateIP(hostname, resolveFn) {
477
489
  }
478
490
  /** Maximum number of redirects to follow in safeFetch. */
479
491
  const MAX_SAFE_REDIRECTS = 5;
492
+ function isRedirectStatus(status) {
493
+ return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
494
+ }
480
495
  /**
481
496
  * Fetch a URL with redirect: "manual", validating each redirect target
482
497
  * against the hostname allowlist and optional DNS-resolved IP (anti-SSRF).
@@ -493,6 +508,13 @@ async function safeFetch(params) {
493
508
  if (!isUrlAllowed(currentUrl, params.allowHosts)) throw new Error(`Initial download URL blocked: ${currentUrl}`);
494
509
  if (currentHeaders.has("authorization") && params.authorizationAllowHosts && !isUrlAllowed(currentUrl, params.authorizationAllowHosts)) currentHeaders.delete("authorization");
495
510
  if (!hasDispatcher) {
511
+ const lookupFn = async (hostname) => {
512
+ const resolved = await resolveFn(hostname);
513
+ return [{
514
+ ...resolved,
515
+ family: resolved.address.includes(":") ? 6 : 4
516
+ }];
517
+ };
496
518
  const guarded = await (0, openclaw_plugin_sdk_ssrf_runtime.fetchWithSsrFGuard)({
497
519
  url: currentUrl,
498
520
  fetchImpl: resolveGuardedFetchImpl({
@@ -506,12 +528,12 @@ async function safeFetch(params) {
506
528
  maxRedirects: MAX_SAFE_REDIRECTS,
507
529
  requireHttps: true,
508
530
  policy: resolveMediaSsrfPolicy(params.allowHosts),
509
- lookupFn: resolveFn,
531
+ lookupFn,
510
532
  retainAuthorizationRedirectHostnameAllowlist: resolveRetainedAuthorizationRedirectHostnameAllowlist(params.authorizationAllowHosts),
511
533
  auditContext: "msteams.attachment",
512
534
  timeoutMs: params.timeoutMs ?? 3e4
513
535
  });
514
- return responseWithRelease(guarded.response, guarded.release);
536
+ return (0, openclaw_plugin_sdk_fetch_runtime.responseWithRelease)(guarded.response, guarded.release);
515
537
  }
516
538
  if (resolveFn) try {
517
539
  const initialHost = new URL(currentUrl).hostname;
@@ -525,13 +547,7 @@ async function safeFetch(params) {
525
547
  headers: currentHeaders,
526
548
  redirect: "manual"
527
549
  });
528
- if (![
529
- 301,
530
- 302,
531
- 303,
532
- 307,
533
- 308
534
- ].includes(res.status)) return res;
550
+ if (!isRedirectStatus(res.status)) return res;
535
551
  const location = res.headers.get("location");
536
552
  if (!location) return res;
537
553
  let redirectUrl;
@@ -656,6 +672,117 @@ function normalizeBotFrameworkServiceUrl(serviceUrl) {
656
672
  throw new Error(`Blocked Microsoft Teams serviceUrl host: ${describeBotFrameworkServiceUrlHost(serviceUrl)}`);
657
673
  }
658
674
  //#endregion
675
+ //#region extensions/msteams/src/qa/private-runtime.ts
676
+ const PRIVATE_QA_BUILD_ENV = "OPENCLAW_BUILD_PRIVATE_QA";
677
+ const PRIVATE_QA_NONCE_HEADER = "x-openclaw-msteams-qa-nonce";
678
+ const PRIVATE_QA_RUNTIME_SYMBOL = Symbol.for("openclaw.msteams.privateQaRuntime");
679
+ var PrivateQaHttpClient = class PrivateQaHttpClient {
680
+ constructor(connectorUrl, nonce, options = {}) {
681
+ this.connectorUrl = connectorUrl;
682
+ this.nonce = nonce;
683
+ this.options = options;
684
+ }
685
+ clone(options = {}) {
686
+ return new PrivateQaHttpClient(this.connectorUrl, this.nonce, {
687
+ ...this.options,
688
+ ...options,
689
+ headers: {
690
+ ...this.options.headers,
691
+ ...options.headers
692
+ }
693
+ });
694
+ }
695
+ async request(config) {
696
+ const sourceUrl = new URL(config.url ?? "", "https://smba.trafficmanager.net");
697
+ const targetUrl = new URL(`${sourceUrl.pathname}${sourceUrl.search}`, this.connectorUrl);
698
+ const headers = new Headers(this.options.headers);
699
+ for (const [key, value] of Object.entries(config.headers ?? {})) if (value != null) headers.set(key, String(value));
700
+ headers.set(PRIVATE_QA_NONCE_HEADER, this.nonce);
701
+ const token = typeof this.options.token === "function" ? await this.options.token() : this.options.token;
702
+ if (token) headers.set("authorization", `Bearer ${token}`);
703
+ const method = String(config.method ?? "GET").toUpperCase();
704
+ const { response, release } = await (0, openclaw_plugin_sdk_ssrf_runtime.fetchWithSsrFGuard)({
705
+ url: targetUrl.toString(),
706
+ init: {
707
+ method,
708
+ headers,
709
+ body: method === "GET" || method === "HEAD" || config.data == null ? void 0 : typeof config.data === "string" ? config.data : JSON.stringify(config.data)
710
+ },
711
+ policy: (0, openclaw_plugin_sdk_ssrf_runtime.ssrfPolicyFromHttpBaseUrlAllowedOrigin)(targetUrl.toString()),
712
+ maxRedirects: 0,
713
+ auditContext: "msteams-private-qa-connector"
714
+ });
715
+ try {
716
+ const text = await response.text();
717
+ const data = text ? JSON.parse(text) : void 0;
718
+ if (!response.ok) throw new Error(`Microsoft Teams private QA connector returned HTTP ${response.status}`);
719
+ return {
720
+ data,
721
+ status: response.status,
722
+ statusText: response.statusText,
723
+ headers: Object.fromEntries(response.headers),
724
+ config
725
+ };
726
+ } finally {
727
+ await release();
728
+ }
729
+ }
730
+ get(url, config = {}) {
731
+ return this.request({
732
+ ...config,
733
+ method: "GET",
734
+ url
735
+ });
736
+ }
737
+ post(url, data, config = {}) {
738
+ return this.request({
739
+ ...config,
740
+ data,
741
+ method: "POST",
742
+ url
743
+ });
744
+ }
745
+ put(url, data, config = {}) {
746
+ return this.request({
747
+ ...config,
748
+ data,
749
+ method: "PUT",
750
+ url
751
+ });
752
+ }
753
+ patch(url, data, config = {}) {
754
+ return this.request({
755
+ ...config,
756
+ data,
757
+ method: "PATCH",
758
+ url
759
+ });
760
+ }
761
+ delete(url, config = {}) {
762
+ return this.request({
763
+ ...config,
764
+ method: "DELETE",
765
+ url
766
+ });
767
+ }
768
+ };
769
+ function resolveMSTeamsPrivateQaRuntime(env = process.env, bootstrap = globalThis[PRIVATE_QA_RUNTIME_SYMBOL]) {
770
+ if (!bootstrap) return;
771
+ if (env[PRIVATE_QA_BUILD_ENV] !== "1") throw new Error("Microsoft Teams private QA runtime requires OPENCLAW_BUILD_PRIVATE_QA=1");
772
+ const connectorUrl = bootstrap.connectorUrl?.trim();
773
+ const nonce = bootstrap.nonce?.trim();
774
+ const botToken = bootstrap.botToken?.trim();
775
+ if (!connectorUrl || !nonce || !botToken) throw new Error("Microsoft Teams private QA bootstrap requires connector URL, nonce, and bot token");
776
+ const parsedConnectorUrl = new URL(connectorUrl);
777
+ if (parsedConnectorUrl.protocol !== "http:" || parsedConnectorUrl.hostname !== "127.0.0.1" && parsedConnectorUrl.hostname !== "localhost") throw new Error("Microsoft Teams private QA connector must use loopback HTTP");
778
+ return {
779
+ client: new PrivateQaHttpClient(parsedConnectorUrl.toString(), nonce),
780
+ listenHost: "127.0.0.1",
781
+ skipAuth: true,
782
+ token: async () => botToken
783
+ };
784
+ }
785
+ //#endregion
659
786
  //#region extensions/msteams/src/user-agent.ts
660
787
  let cachedUserAgent;
661
788
  function resolveTeamsSdkVersion() {
@@ -733,20 +860,26 @@ async function createMSTeamsExpressAdapter(serverOrApp) {
733
860
  */
734
861
  async function createMSTeamsApp(creds, options) {
735
862
  const { App, cloudFromName } = await loadSdkModules();
863
+ const privateQaRuntime = resolveMSTeamsPrivateQaRuntime();
736
864
  const cloud = options?.cloud ?? "Public";
737
865
  const serviceUrl = options?.serviceUrl ? normalizeBotFrameworkServiceUrl(options.serviceUrl) : void 0;
738
866
  const appOptions = {
739
- client: options?.httpClient ?? {
867
+ client: privateQaRuntime?.client ?? options?.httpClient ?? {
740
868
  headers: { "User-Agent": buildOpenClawUserAgentFragment() },
741
869
  timeout: 3e4
742
870
  },
871
+ ...privateQaRuntime ? {
872
+ clientSecret: "",
873
+ skipAuth: privateQaRuntime.skipAuth,
874
+ token: privateQaRuntime.token
875
+ } : {},
743
876
  ...options?.httpServerAdapter ? { httpServerAdapter: options.httpServerAdapter } : {},
744
877
  ...options?.messagingEndpoint ? { messagingEndpoint: options.messagingEndpoint } : {},
745
878
  cloud: cloudFromName(cloud),
746
879
  ...serviceUrl ? { serviceUrl } : {},
747
880
  ...options?.oauthDefaultConnectionName ? { oauth: { defaultConnectionName: options.oauthDefaultConnectionName } } : {}
748
881
  };
749
- if (creds.type === "federated") return createFederatedApp(creds, App, appOptions);
882
+ if (creds.type === "federated") return await createFederatedApp(creds, App, appOptions);
750
883
  return new App({
751
884
  clientId: creds.appId,
752
885
  clientSecret: creds.appPassword,
@@ -754,7 +887,7 @@ async function createMSTeamsApp(creds, options) {
754
887
  ...appOptions
755
888
  });
756
889
  }
757
- function createFederatedApp(creds, App, appOptions) {
890
+ async function createFederatedApp(creds, App, appOptions) {
758
891
  if (creds.useManagedIdentity) return new App({
759
892
  clientId: creds.appId,
760
893
  tenantId: creds.tenantId,
@@ -764,9 +897,9 @@ function createFederatedApp(creds, App, appOptions) {
764
897
  if (!creds.certificatePath) throw new Error("Federated credentials require either a certificate path or managed identity.");
765
898
  let privateKey;
766
899
  try {
767
- privateKey = node_fs.readFileSync(creds.certificatePath, "utf-8");
900
+ privateKey = await (0, openclaw_plugin_sdk_secret_file.readSecretFile)(creds.certificatePath, "Microsoft Teams certificate");
768
901
  } catch (err) {
769
- const msg = err instanceof Error ? err.message : String(err);
902
+ const msg = (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err);
770
903
  throw new Error(`Failed to read certificate file at '${creds.certificatePath}': ${msg}`, { cause: err });
771
904
  }
772
905
  return createCertificateApp(creds, privateKey, App, appOptions);
@@ -854,6 +987,10 @@ function createMSTeamsTokenBody(params) {
854
987
  function resolveMSTeamsTokenExpiresAt(value) {
855
988
  return (0, openclaw_plugin_sdk_number_runtime.resolveExpiresAtMsFromDurationSeconds)(value, { bufferMs: EXPIRY_BUFFER_MS });
856
989
  }
990
+ function assertMSTeamsTokenResponseObject(data, failureLabel) {
991
+ if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(data)) throw new Error(`MSTeams ${failureLabel} failed: invalid token response fields`);
992
+ return data;
993
+ }
857
994
  function parseMSTeamsTokenResponse(data, failureLabel) {
858
995
  const expiresAt = resolveMSTeamsTokenExpiresAt(data.expires_in);
859
996
  if (typeof data.access_token !== "string" || !data.access_token || expiresAt === void 0 || data.refresh_token !== void 0 && typeof data.refresh_token !== "string" || data.scope !== void 0 && typeof data.scope !== "string") throw new Error(`MSTeams ${failureLabel} failed: invalid token response fields`);
@@ -880,7 +1017,7 @@ async function fetchMSTeamsTokens(params) {
880
1017
  });
881
1018
  try {
882
1019
  if (!response.ok) throw await createMSTeamsHttpError(response, `MSTeams ${params.failureLabel} failed`);
883
- return parseMSTeamsTokenResponse(await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(response, `MSTeams ${params.failureLabel} failed`), params.failureLabel);
1020
+ return parseMSTeamsTokenResponse(assertMSTeamsTokenResponseObject(await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(response, `MSTeams ${params.failureLabel} failed`), params.failureLabel), params.failureLabel);
884
1021
  } finally {
885
1022
  await release();
886
1023
  }
@@ -948,12 +1085,16 @@ function resolveAuthType(cfg) {
948
1085
  if (process.env.MSTEAMS_AUTH_TYPE === "federated") return "federated";
949
1086
  return "secret";
950
1087
  }
1088
+ function resolveFederatedPath(configValue, envValue) {
1089
+ if ((0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(configValue)) return configValue;
1090
+ if ((0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(envValue)) return envValue;
1091
+ }
951
1092
  function hasConfiguredMSTeamsCredentials(cfg) {
952
1093
  const authType = resolveAuthType(cfg);
953
1094
  const hasAppId = Boolean((0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.appId) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_APP_ID));
954
1095
  const hasTenantId = Boolean((0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.tenantId) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_TENANT_ID));
955
1096
  if (authType === "federated") {
956
- const hasCert = Boolean(cfg?.certificatePath || process.env.MSTEAMS_CERTIFICATE_PATH);
1097
+ const hasCert = Boolean(resolveFederatedPath(cfg?.certificatePath, process.env.MSTEAMS_CERTIFICATE_PATH));
957
1098
  const hasManagedIdentity = cfg?.useManagedIdentity ?? process.env.MSTEAMS_USE_MANAGED_IDENTITY === "true";
958
1099
  return hasAppId && hasTenantId && (hasCert || hasManagedIdentity);
959
1100
  }
@@ -965,7 +1106,7 @@ function resolveMSTeamsCredentials(cfg) {
965
1106
  const tenantId = (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(cfg?.tenantId) || (0, openclaw_plugin_sdk_secret_input.normalizeSecretInputString)(process.env.MSTEAMS_TENANT_ID);
966
1107
  if (!appId || !tenantId) return;
967
1108
  if (authType === "federated") {
968
- const certificatePath = cfg?.certificatePath || process.env.MSTEAMS_CERTIFICATE_PATH || void 0;
1109
+ const certificatePath = resolveFederatedPath(cfg?.certificatePath, process.env.MSTEAMS_CERTIFICATE_PATH);
969
1110
  const certificateThumbprint = cfg?.certificateThumbprint || process.env.MSTEAMS_CERTIFICATE_THUMBPRINT || void 0;
970
1111
  const useManagedIdentity = cfg?.useManagedIdentity ?? process.env.MSTEAMS_USE_MANAGED_IDENTITY === "true";
971
1112
  const managedIdentityClientId = cfg?.managedIdentityClientId || process.env.MSTEAMS_MANAGED_IDENTITY_CLIENT_ID || void 0;
@@ -1046,21 +1187,30 @@ async function requestGraph(params) {
1046
1187
  try {
1047
1188
  if (!response.ok) throw await createMSTeamsHttpError(response, `${params.errorPrefix ?? "Graph"} ${params.path} failed`);
1048
1189
  releaseInFinally = false;
1049
- return responseWithRelease(response, release);
1190
+ return (0, openclaw_plugin_sdk_fetch_runtime.responseWithRelease)(response, release);
1050
1191
  } finally {
1051
1192
  if (releaseInFinally) await release();
1052
1193
  }
1053
1194
  }
1054
1195
  async function readOptionalGraphJson(res, label) {
1055
- if (res.status === 204 || res.headers?.get?.("content-length") === "0") return;
1196
+ if (res.status === 204 || res.headers.get("content-length") === "0") return;
1056
1197
  return await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(res, label);
1057
1198
  }
1058
- async function fetchGraphJson(params) {
1059
- return await readOptionalGraphJson(await requestGraph({
1199
+ async function mutateGraphJson(params) {
1200
+ const errorPrefix = `Graph${params.beta ? " beta" : ""} ${params.method}`;
1201
+ return readOptionalGraphJson(await requestGraph({
1060
1202
  token: params.token,
1061
1203
  path: params.path,
1062
1204
  method: params.method,
1063
1205
  body: params.body,
1206
+ root: params.beta ? GRAPH_BETA : void 0,
1207
+ errorPrefix
1208
+ }), `${errorPrefix} ${params.path} failed`);
1209
+ }
1210
+ async function fetchGraphJson(params) {
1211
+ return await readOptionalGraphJson(await requestGraph({
1212
+ token: params.token,
1213
+ path: params.path,
1064
1214
  headers: params.headers,
1065
1215
  deadline: params.deadline
1066
1216
  }), `Graph ${params.path} failed`);
@@ -1155,41 +1305,13 @@ async function listTeamsByNameWithPageInfo(token, query) {
1155
1305
  path: `/groups?$filter=${encodeURIComponent(filter)}&$select=id,displayName`
1156
1306
  });
1157
1307
  }
1158
- async function postGraphJson(params) {
1159
- return readOptionalGraphJson(await requestGraph({
1160
- token: params.token,
1161
- path: params.path,
1162
- method: "POST",
1163
- body: params.body,
1164
- errorPrefix: "Graph POST"
1165
- }), `Graph POST ${params.path} failed`);
1166
- }
1167
- async function postGraphBetaJson(params) {
1168
- return readOptionalGraphJson(await requestGraph({
1169
- token: params.token,
1170
- path: params.path,
1171
- method: "POST",
1172
- root: GRAPH_BETA,
1173
- body: params.body,
1174
- errorPrefix: "Graph beta POST"
1175
- }), `Graph beta POST ${params.path} failed`);
1176
- }
1177
1308
  async function deleteGraphRequest(params) {
1178
- await requestGraph({
1309
+ await (await requestGraph({
1179
1310
  token: params.token,
1180
1311
  path: params.path,
1181
1312
  method: "DELETE",
1182
1313
  errorPrefix: "Graph DELETE"
1183
- });
1184
- }
1185
- async function patchGraphJson(params) {
1186
- return readOptionalGraphJson(await requestGraph({
1187
- token: params.token,
1188
- path: params.path,
1189
- method: "PATCH",
1190
- body: params.body,
1191
- errorPrefix: "Graph PATCH"
1192
- }), `Graph PATCH ${params.path} failed`);
1314
+ })).body?.cancel().catch(() => void 0);
1193
1315
  }
1194
1316
  async function listChannelsForTeam(token, teamId) {
1195
1317
  return (await listChannelsForTeamWithPageInfo(token, teamId)).items;
@@ -1238,6 +1360,7 @@ async function findGraphUsersByExactIdentity(params) {
1238
1360
  }
1239
1361
  //#endregion
1240
1362
  //#region extensions/msteams/src/resolve-allowlist.ts
1363
+ const MSTEAMS_GROUP_CONVERSATION_ID = /^19:.+@thread\.(?:tacv2|skype|v2)$/i;
1241
1364
  function normalizeExactMatch(value) {
1242
1365
  return (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(value ?? "");
1243
1366
  }
@@ -1280,6 +1403,16 @@ function projectStableMSTeamsUserAllowlist(entries) {
1280
1403
  const projected = entries.map((entry) => normalizeStaticMSTeamsAllowEntry(entry)).filter((entry) => Boolean(entry));
1281
1404
  return [...new Map(projected.map((entry) => [normalizeExactMatch(entry), entry])).values()];
1282
1405
  }
1406
+ function projectStableMSTeamsGroupAllowlist(entries) {
1407
+ if (!entries) return;
1408
+ const projected = entries.map((entry) => {
1409
+ const stableUserEntry = normalizeStaticMSTeamsAllowEntry(entry);
1410
+ if (stableUserEntry) return stableUserEntry;
1411
+ const conversationId = normalizeMSTeamsConversationId(normalizeMSTeamsUserInput(entry));
1412
+ return MSTEAMS_GROUP_CONVERSATION_ID.test(conversationId) ? conversationId : void 0;
1413
+ }).filter((entry) => Boolean(entry));
1414
+ return [...new Map(projected.map((entry) => [MSTEAMS_GROUP_CONVERSATION_ID.test(entry) ? `conversation:${entry}` : normalizeExactMatch(entry), entry])).values()];
1415
+ }
1283
1416
  function stripProviderPrefix(raw) {
1284
1417
  return raw.replace(/^(msteams|teams):/i, "");
1285
1418
  }
@@ -1311,7 +1444,7 @@ function parseMSTeamsConversationId(raw) {
1311
1444
  *
1312
1445
  * Accepts both prefixed and bare formats:
1313
1446
  * - `conversation:<id>` — explicit conversation prefix
1314
- * - `19:abc@thread.tacv2` / `19:abc@thread.skype` — channel / legacy group
1447
+ * - `19:abc@thread.tacv2` / `19:abc@thread.skype` / `19:abc@thread.v2` — group or channel
1315
1448
  * - `19:{userId}_{appId}@unq.gbl.spaces` — Graph 1:1 chat thread format
1316
1449
  * - `a:1xxx` — Bot Framework personal (1:1) chat id
1317
1450
  * - `8:orgid:xxx` — Bot Framework org-scoped personal chat id
@@ -1320,7 +1453,7 @@ function looksLikeMSTeamsConversationId(raw) {
1320
1453
  const trimmed = raw.trim();
1321
1454
  if (!trimmed) return false;
1322
1455
  if (/^conversation:/i.test(trimmed)) return true;
1323
- if (/^19:.+@thread\.(tacv2|skype)$/i.test(trimmed)) return true;
1456
+ if (MSTEAMS_GROUP_CONVERSATION_ID.test(trimmed)) return true;
1324
1457
  if (/^19:.+@unq\.gbl\.spaces$/i.test(trimmed)) return true;
1325
1458
  if (/^a:1[A-Za-z0-9_-]+$/i.test(trimmed)) return true;
1326
1459
  if (/^8:orgid:[A-Za-z0-9-]+$/i.test(trimmed)) return true;
@@ -1331,7 +1464,7 @@ function looksLikeMSTeamsConversationId(raw) {
1331
1464
  * can forward verbatim to the channel adapter.
1332
1465
  */
1333
1466
  function looksLikeMSTeamsTargetId(raw) {
1334
- const trimmed = raw.trim();
1467
+ const trimmed = stripProviderPrefix(raw.trim()).trim();
1335
1468
  if (looksLikeMSTeamsConversationId(trimmed)) return true;
1336
1469
  if (/^user:/i.test(trimmed)) {
1337
1470
  const id = trimmed.slice(5).trim();
@@ -1805,6 +1938,18 @@ Object.defineProperty(exports, "extractInlineImageCandidates", {
1805
1938
  return extractInlineImageCandidates;
1806
1939
  }
1807
1940
  });
1941
+ Object.defineProperty(exports, "extractMSTeamsConversationMessageId", {
1942
+ enumerable: true,
1943
+ get: function() {
1944
+ return extractMSTeamsConversationMessageId;
1945
+ }
1946
+ });
1947
+ Object.defineProperty(exports, "extractMSTeamsQuoteInfo", {
1948
+ enumerable: true,
1949
+ get: function() {
1950
+ return extractMSTeamsQuoteInfo;
1951
+ }
1952
+ });
1808
1953
  Object.defineProperty(exports, "fetchGraphAbsoluteUrl", {
1809
1954
  enumerable: true,
1810
1955
  get: function() {
@@ -1847,6 +1992,12 @@ Object.defineProperty(exports, "isLikelyImageAttachment", {
1847
1992
  return isLikelyImageAttachment;
1848
1993
  }
1849
1994
  });
1995
+ Object.defineProperty(exports, "isRedirectStatus", {
1996
+ enumerable: true,
1997
+ get: function() {
1998
+ return isRedirectStatus;
1999
+ }
2000
+ });
1850
2001
  Object.defineProperty(exports, "isUrlAllowed", {
1851
2002
  enumerable: true,
1852
2003
  get: function() {
@@ -1895,6 +2046,12 @@ Object.defineProperty(exports, "looksLikeMSTeamsTargetId", {
1895
2046
  return looksLikeMSTeamsTargetId;
1896
2047
  }
1897
2048
  });
2049
+ Object.defineProperty(exports, "mutateGraphJson", {
2050
+ enumerable: true,
2051
+ get: function() {
2052
+ return mutateGraphJson;
2053
+ }
2054
+ });
1898
2055
  Object.defineProperty(exports, "normalizeBotFrameworkServiceUrl", {
1899
2056
  enumerable: true,
1900
2057
  get: function() {
@@ -1907,6 +2064,12 @@ Object.defineProperty(exports, "normalizeContentType", {
1907
2064
  return normalizeContentType;
1908
2065
  }
1909
2066
  });
2067
+ Object.defineProperty(exports, "normalizeMSTeamsConversationId", {
2068
+ enumerable: true,
2069
+ get: function() {
2070
+ return normalizeMSTeamsConversationId;
2071
+ }
2072
+ });
1910
2073
  Object.defineProperty(exports, "normalizeMSTeamsMessagingTarget", {
1911
2074
  enumerable: true,
1912
2075
  get: function() {
@@ -1925,6 +2088,12 @@ Object.defineProperty(exports, "normalizeQuery", {
1925
2088
  return normalizeQuery;
1926
2089
  }
1927
2090
  });
2091
+ Object.defineProperty(exports, "parseMSTeamsActivityTimestamp", {
2092
+ enumerable: true,
2093
+ get: function() {
2094
+ return parseMSTeamsActivityTimestamp;
2095
+ }
2096
+ });
1928
2097
  Object.defineProperty(exports, "parseMSTeamsConversationId", {
1929
2098
  enumerable: true,
1930
2099
  get: function() {
@@ -1943,22 +2112,10 @@ Object.defineProperty(exports, "parseMSTeamsTeamEntry", {
1943
2112
  return parseMSTeamsTeamEntry;
1944
2113
  }
1945
2114
  });
1946
- Object.defineProperty(exports, "patchGraphJson", {
1947
- enumerable: true,
1948
- get: function() {
1949
- return patchGraphJson;
1950
- }
1951
- });
1952
- Object.defineProperty(exports, "postGraphBetaJson", {
2115
+ Object.defineProperty(exports, "projectStableMSTeamsGroupAllowlist", {
1953
2116
  enumerable: true,
1954
2117
  get: function() {
1955
- return postGraphBetaJson;
1956
- }
1957
- });
1958
- Object.defineProperty(exports, "postGraphJson", {
1959
- enumerable: true,
1960
- get: function() {
1961
- return postGraphJson;
2118
+ return projectStableMSTeamsGroupAllowlist;
1962
2119
  }
1963
2120
  });
1964
2121
  Object.defineProperty(exports, "projectStableMSTeamsTeamsConfig", {
@@ -2009,6 +2166,12 @@ Object.defineProperty(exports, "resolveMSTeamsMediaKind", {
2009
2166
  return resolveMSTeamsMediaKind;
2010
2167
  }
2011
2168
  });
2169
+ Object.defineProperty(exports, "resolveMSTeamsPrivateQaRuntime", {
2170
+ enumerable: true,
2171
+ get: function() {
2172
+ return resolveMSTeamsPrivateQaRuntime;
2173
+ }
2174
+ });
2012
2175
  Object.defineProperty(exports, "resolveMSTeamsRequestTimeoutMs", {
2013
2176
  enumerable: true,
2014
2177
  get: function() {
@@ -2075,6 +2238,12 @@ Object.defineProperty(exports, "searchGraphUsers", {
2075
2238
  return searchGraphUsers;
2076
2239
  }
2077
2240
  });
2241
+ Object.defineProperty(exports, "stripMSTeamsMentionTags", {
2242
+ enumerable: true,
2243
+ get: function() {
2244
+ return stripMSTeamsMentionTags;
2245
+ }
2246
+ });
2078
2247
  Object.defineProperty(exports, "tryBuildGraphSharesUrlForSharedLink", {
2079
2248
  enumerable: true,
2080
2249
  get: function() {
@@ -2093,6 +2262,12 @@ Object.defineProperty(exports, "validateMSTeamsProactiveServiceUrlBoundary", {
2093
2262
  return validateMSTeamsProactiveServiceUrlBoundary;
2094
2263
  }
2095
2264
  });
2265
+ Object.defineProperty(exports, "wasMSTeamsBotMentioned", {
2266
+ enumerable: true,
2267
+ get: function() {
2268
+ return wasMSTeamsBotMentioned;
2269
+ }
2270
+ });
2096
2271
  Object.defineProperty(exports, "withMSTeamsAbortableRequestTimeout", {
2097
2272
  enumerable: true,
2098
2273
  get: function() {
@@ -0,0 +1,28 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+ //#endregion
23
+ Object.defineProperty(exports, "__toESM", {
24
+ enumerable: true,
25
+ get: function() {
26
+ return __toESM;
27
+ }
28
+ });