@openclaw/msteams 2026.5.7 → 2026.5.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.
package/dist/api.js CHANGED
@@ -1,3 +1,3 @@
1
- import { t as msteamsPlugin } from "./channel-BOwKBAvY.js";
2
- import { i as msteamsSetupAdapter, n as openDelegatedOAuthUrl, r as createMSTeamsSetupWizardBase, t as msteamsSetupWizard } from "./setup-surface-BLkFQYIQ.js";
1
+ import { t as msteamsPlugin } from "./channel-kz4Rzh2w.js";
2
+ import { i as msteamsSetupAdapter, n as openDelegatedOAuthUrl, r as createMSTeamsSetupWizardBase, t as msteamsSetupWizard } from "./setup-surface-C7d0jGM5.js";
3
3
  export { createMSTeamsSetupWizardBase, msteamsPlugin, msteamsSetupAdapter, msteamsSetupWizard, openDelegatedOAuthUrl };
@@ -1,13 +1,14 @@
1
- import { o as buildProbeChannelStatusSummary, r as PAIRING_APPROVED_MESSAGE, s as chunkTextForOutbound, t as DEFAULT_ACCOUNT_ID, u as createDefaultChannelRuntimeState } from "./runtime-api-DV1iVMn1.js";
2
- import { h as resolveMSTeamsCredentials } from "./graph-users-9uQJepqr.js";
3
- import { a as parseMSTeamsTeamChannelInput, c as resolveMSTeamsUserAllowlist, i as parseMSTeamsConversationId, n as normalizeMSTeamsMessagingTarget, r as normalizeMSTeamsUserInput, s as resolveMSTeamsChannelAllowlist, t as looksLikeMSTeamsTargetId } from "./resolve-allowlist-D41JSziq.js";
1
+ import { o as buildProbeChannelStatusSummary, r as PAIRING_APPROVED_MESSAGE, s as chunkTextForOutbound, t as DEFAULT_ACCOUNT_ID, u as createDefaultChannelRuntimeState } from "./runtime-api-C3EIaIpt.js";
2
+ import { h as resolveMSTeamsCredentials } from "./graph-users-CCU0WVMZ.js";
3
+ import { a as parseMSTeamsTeamChannelInput, c as resolveMSTeamsUserAllowlist, i as parseMSTeamsConversationId, n as normalizeMSTeamsMessagingTarget, r as normalizeMSTeamsUserInput, s as resolveMSTeamsChannelAllowlist, t as looksLikeMSTeamsTargetId } from "./resolve-allowlist-7CHP2hEA.js";
4
4
  import { t as MSTeamsChannelConfigSchema } from "./config-schema-DwOEthCC.js";
5
- import { r as resolveMSTeamsGroupToolPolicy } from "./policy-DTnU2GR7.js";
6
- import { i as msteamsSetupAdapter, t as msteamsSetupWizard } from "./setup-surface-BLkFQYIQ.js";
5
+ import { n as resolveMSTeamsGroupToolPolicy } from "./policy-bM71GXRd.js";
6
+ import { i as msteamsSetupAdapter, t as msteamsSetupWizard } from "./setup-surface-C7d0jGM5.js";
7
7
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
8
8
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
9
9
  import { createTopLevelChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
10
10
  import { buildChannelOutboundSessionRoute, createChatChannelPlugin, stripChannelTargetPrefix, stripTargetKindPrefix } from "openclaw/plugin-sdk/channel-core";
11
+ import { createChannelMessageAdapterFromOutbound } from "openclaw/plugin-sdk/channel-message";
11
12
  import { createPairingPrefixStripper } from "openclaw/plugin-sdk/channel-pairing";
12
13
  import { createAllowlistProviderGroupPolicyWarningCollector, createDangerousNameMatchingMutableAllowlistWarningCollector, projectConfigWarningCollector } from "openclaw/plugin-sdk/channel-policy";
13
14
  import { createChannelDirectoryAdapter, createRuntimeDirectoryLiveAdapter, listDirectoryEntriesFromSources } from "openclaw/plugin-sdk/directory-runtime";
@@ -182,7 +183,7 @@ const collectMSTeamsSecurityWarnings = createAllowlistProviderGroupPolicyWarning
182
183
  resolveGroupPolicy: ({ cfg }) => cfg.channels?.msteams?.groupPolicy,
183
184
  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."] : []
184
185
  });
185
- const loadMSTeamsChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-BC1ruIfN.js"), "msTeamsChannelRuntime");
186
+ const loadMSTeamsChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-C1IGCVBT.js"), "msTeamsChannelRuntime");
186
187
  const resolveMSTeamsChannelConfig = (cfg) => ({
187
188
  allowFrom: cfg.channels?.msteams?.allowFrom,
188
189
  defaultTo: cfg.channels?.msteams?.defaultTo
@@ -376,6 +377,41 @@ function describeMSTeamsMessageTool({ cfg }) {
376
377
  } : null
377
378
  };
378
379
  }
380
+ const msteamsChannelOutbound = {
381
+ deliveryMode: "direct",
382
+ chunker: chunkTextForOutbound,
383
+ chunkerMode: "markdown",
384
+ textChunkLimit: 4e3,
385
+ pollMaxOptions: 12,
386
+ deliveryCapabilities: { durableFinal: {
387
+ text: true,
388
+ media: true,
389
+ messageSendingHooks: true
390
+ } },
391
+ ...createRuntimeOutboundDelegates({
392
+ getRuntime: loadMSTeamsChannelRuntime,
393
+ sendText: { resolve: (runtime) => runtime.msteamsOutbound.sendText },
394
+ sendMedia: { resolve: (runtime) => runtime.msteamsOutbound.sendMedia },
395
+ sendPoll: { resolve: (runtime) => runtime.msteamsOutbound.sendPoll }
396
+ })
397
+ };
398
+ const msteamsMessageAdapter = createChannelMessageAdapterFromOutbound({
399
+ id: "msteams",
400
+ outbound: msteamsChannelOutbound,
401
+ live: {
402
+ capabilities: {
403
+ draftPreview: true,
404
+ previewFinalization: true,
405
+ progressUpdates: true,
406
+ nativeStreaming: true
407
+ },
408
+ finalizer: { capabilities: {
409
+ finalEdit: true,
410
+ normalFallback: true,
411
+ previewReceipt: true
412
+ } }
413
+ }
414
+ });
379
415
  const msteamsPlugin = createChatChannelPlugin({
380
416
  base: {
381
417
  id: "msteams",
@@ -428,6 +464,7 @@ const msteamsPlugin = createChatChannelPlugin({
428
464
  hint: "<conversationId|user:ID|conversation:ID>"
429
465
  }
430
466
  },
467
+ message: msteamsMessageAdapter,
431
468
  directory: createChannelDirectoryAdapter({
432
469
  self: async ({ cfg }) => {
433
470
  const creds = resolveMSTeamsCredentials(cfg.channels?.msteams);
@@ -928,7 +965,7 @@ const msteamsPlugin = createChatChannelPlugin({
928
965
  })
929
966
  }),
930
967
  gateway: { startAccount: async (ctx) => {
931
- const { monitorMSTeamsProvider } = await import("./src-CP7V_TeZ.js");
968
+ const { monitorMSTeamsProvider } = await import("./src-DQ7ARgDd.js");
932
969
  const port = ctx.cfg.channels?.msteams?.webhook?.port ?? 3978;
933
970
  ctx.setStatus({
934
971
  accountId: ctx.accountId,
@@ -966,19 +1003,7 @@ const msteamsPlugin = createChatChannelPlugin({
966
1003
  hasRepliedRef
967
1004
  };
968
1005
  } },
969
- outbound: {
970
- deliveryMode: "direct",
971
- chunker: chunkTextForOutbound,
972
- chunkerMode: "markdown",
973
- textChunkLimit: 4e3,
974
- pollMaxOptions: 12,
975
- ...createRuntimeOutboundDelegates({
976
- getRuntime: loadMSTeamsChannelRuntime,
977
- sendText: { resolve: (runtime) => runtime.msteamsOutbound.sendText },
978
- sendMedia: { resolve: (runtime) => runtime.msteamsOutbound.sendMedia },
979
- sendPoll: { resolve: (runtime) => runtime.msteamsOutbound.sendPoll }
980
- })
981
- }
1006
+ outbound: msteamsChannelOutbound
982
1007
  });
983
1008
  //#endregion
984
1009
  export { msteamsPlugin as t };
@@ -1,2 +1,2 @@
1
- import { t as msteamsPlugin } from "./channel-BOwKBAvY.js";
1
+ import { t as msteamsPlugin } from "./channel-kz4Rzh2w.js";
2
2
  export { msteamsPlugin };
@@ -1,6 +1,6 @@
1
- import { s as chunkTextForOutbound } from "./runtime-api-DV1iVMn1.js";
2
- import { a as fetchGraphJson, c as normalizeQuery, d as postGraphJson, f as resolveGraphToken, i as fetchGraphAbsoluteUrl, l as patchGraphJson, n as deleteGraphRequest, o as listChannelsForTeam, r as escapeOData, s as listTeamsByName, t as searchGraphUsers, u as postGraphBetaJson } from "./graph-users-9uQJepqr.js";
3
- import { S as createMSTeamsConversationStoreFs, a as sendMessageMSTeams, b as createMSTeamsPollStoreFs, i as sendAdaptiveCardMSTeams, n as deleteMessageMSTeams, o as sendPollMSTeams, r as editMessageMSTeams, t as probeMSTeams } from "./probe-D_H8yFps.js";
1
+ import { s as chunkTextForOutbound } from "./runtime-api-C3EIaIpt.js";
2
+ import { a as fetchGraphJson, c as normalizeQuery, d as postGraphJson, f as resolveGraphToken, i as fetchGraphAbsoluteUrl, l as patchGraphJson, n as deleteGraphRequest, o as listChannelsForTeam, r as escapeOData, s as listTeamsByName, t as searchGraphUsers, u as postGraphBetaJson } from "./graph-users-CCU0WVMZ.js";
3
+ import { S as createMSTeamsConversationStoreFs, a as sendMessageMSTeams, b as createMSTeamsPollStoreFs, i as sendAdaptiveCardMSTeams, n as deleteMessageMSTeams, o as sendPollMSTeams, r as editMessageMSTeams, t as probeMSTeams } from "./probe-CQKmxtlj.js";
4
4
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
5
5
  import { createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
6
6
  import { resolveOutboundSendDep } from "openclaw/plugin-sdk/outbound-send-deps";
@@ -1,14 +1,15 @@
1
- import { L as getMSTeamsRuntime, g as fetchWithSsrFGuard$1 } from "./runtime-api-DV1iVMn1.js";
1
+ import { M as getMSTeamsRuntime, h as fetchWithSsrFGuard$1 } from "./runtime-api-C3EIaIpt.js";
2
2
  import { n as refreshMSTeamsDelegatedTokens } from "./oauth.token-xxpoLWy5.js";
3
3
  import { createRequire } from "node:module";
4
- import { isRecord as isRecord$1, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
4
+ import { isRecord as isRecord$2, normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
5
5
  import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
6
6
  import { Buffer } from "node:buffer";
7
7
  import { lookup } from "node:dns/promises";
8
8
  import { buildHostnameAllowlistPolicyFromSuffixAllowlist, isHttpsUrlAllowedByHostnameSuffixAllowlist, isPrivateIpAddress, normalizeHostnameSuffixAllowlist } from "openclaw/plugin-sdk/ssrf-policy";
9
- import * as fs$1 from "node:fs";
10
- import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
11
- import path, { dirname } from "node:path";
9
+ import * as fs from "node:fs";
10
+ import { readFileSync } from "node:fs";
11
+ import path, { basename, dirname } from "node:path";
12
+ import { privateFileStoreSync } from "openclaw/plugin-sdk/security-runtime";
12
13
  import { hasConfiguredSecretInput, normalizeResolvedSecretInputString, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
13
14
  //#region extensions/msteams/src/attachments/shared.ts
14
15
  const IMAGE_EXT_RE = /\.(avif|bmp|gif|heic|heif|jpe?g|png|tiff?|webp)$/i;
@@ -122,7 +123,7 @@ function tryBuildGraphSharesUrlForSharedLink(url) {
122
123
  function readNestedString(value, keys) {
123
124
  let current = value;
124
125
  for (const key of keys) {
125
- if (!isRecord$1(current)) return;
126
+ if (!isRecord$2(current)) return;
126
127
  current = current[key];
127
128
  }
128
129
  return normalizeOptionalString(current);
@@ -153,7 +154,7 @@ function isLikelyImageAttachment(att) {
153
154
  const name = typeof att.name === "string" ? att.name : "";
154
155
  if (contentType.startsWith("image/")) return true;
155
156
  if (IMAGE_EXT_RE.test(name)) return true;
156
- if (contentType === "application/vnd.microsoft.teams.file.download.info" && isRecord$1(att.content)) {
157
+ if (contentType === "application/vnd.microsoft.teams.file.download.info" && isRecord$2(att.content)) {
157
158
  const fileType = typeof att.content.fileType === "string" ? att.content.fileType : "";
158
159
  if (fileType && IMAGE_EXT_RE.test(`x.${fileType}`)) return true;
159
160
  const fileName = typeof att.content.fileName === "string" ? att.content.fileName : "";
@@ -166,7 +167,7 @@ function isLikelyImageAttachment(att) {
166
167
  * Used when downloading all files, not just images.
167
168
  */
168
169
  function isDownloadableAttachment(att) {
169
- if ((normalizeContentType(att.contentType) ?? "") === "application/vnd.microsoft.teams.file.download.info" && isRecord$1(att.content) && typeof att.content.downloadUrl === "string") return true;
170
+ if ((normalizeContentType(att.contentType) ?? "") === "application/vnd.microsoft.teams.file.download.info" && isRecord$2(att.content) && typeof att.content.downloadUrl === "string") return true;
170
171
  if (typeof att.contentUrl === "string" && att.contentUrl.trim()) return true;
171
172
  return false;
172
173
  }
@@ -176,7 +177,7 @@ function isHtmlAttachment(att) {
176
177
  function extractHtmlFromAttachment(att) {
177
178
  if (!isHtmlAttachment(att)) return;
178
179
  if (typeof att.content === "string") return att.content;
179
- if (!isRecord$1(att.content)) return;
180
+ if (!isRecord$2(att.content)) return;
180
181
  return typeof att.content.text === "string" ? att.content.text : typeof att.content.body === "string" ? att.content.body : typeof att.content.content === "string" ? att.content.content : void 0;
181
182
  }
182
183
  function isLikelyBase64Payload(value) {
@@ -387,7 +388,7 @@ async function safeFetchWithPolicy(params) {
387
388
  }
388
389
  //#endregion
389
390
  //#region extensions/msteams/src/errors.ts
390
- function isRecord(value) {
391
+ function isRecord$1(value) {
391
392
  return typeof value === "object" && value !== null && !Array.isArray(value);
392
393
  }
393
394
  function formatUnknownError(err) {
@@ -405,7 +406,7 @@ function formatUnknownError(err) {
405
406
  }
406
407
  }
407
408
  function extractStatusCode(err) {
408
- if (!isRecord(err)) return null;
409
+ if (!isRecord$1(err)) return null;
409
410
  const direct = err.statusCode ?? err.status;
410
411
  if (typeof direct === "number" && Number.isFinite(direct)) return direct;
411
412
  if (typeof direct === "string") {
@@ -413,7 +414,7 @@ function extractStatusCode(err) {
413
414
  if (Number.isFinite(parsed)) return parsed;
414
415
  }
415
416
  const response = err.response;
416
- if (isRecord(response)) {
417
+ if (isRecord$1(response)) {
417
418
  const status = response.status;
418
419
  if (typeof status === "number" && Number.isFinite(status)) return status;
419
420
  if (typeof status === "string") {
@@ -424,20 +425,20 @@ function extractStatusCode(err) {
424
425
  return null;
425
426
  }
426
427
  function extractErrorCode(err) {
427
- if (!isRecord(err)) return null;
428
+ if (!isRecord$1(err)) return null;
428
429
  const direct = err.code;
429
430
  if (typeof direct === "string" && direct.trim()) return direct;
430
431
  const response = err.response;
431
- if (!isRecord(response)) return null;
432
+ if (!isRecord$1(response)) return null;
432
433
  const body = response.body;
433
- if (isRecord(body)) {
434
+ if (isRecord$1(body)) {
434
435
  const error = body.error;
435
- if (isRecord(error) && typeof error.code === "string" && error.code.trim()) return error.code;
436
+ if (isRecord$1(error) && typeof error.code === "string" && error.code.trim()) return error.code;
436
437
  }
437
438
  return null;
438
439
  }
439
440
  function extractRetryAfterMs(err) {
440
- if (!isRecord(err)) return null;
441
+ if (!isRecord$1(err)) return null;
441
442
  const direct = err.retryAfterMs ?? err.retry_after_ms;
442
443
  if (typeof direct === "number" && Number.isFinite(direct) && direct >= 0) return direct;
443
444
  const retryAfter = err.retryAfter ?? err.retry_after;
@@ -447,10 +448,10 @@ function extractRetryAfterMs(err) {
447
448
  if (Number.isFinite(parsed) && parsed >= 0) return parsed * 1e3;
448
449
  }
449
450
  const response = err.response;
450
- if (!isRecord(response)) return null;
451
+ if (!isRecord$1(response)) return null;
451
452
  const headers = response.headers;
452
453
  if (!headers) return null;
453
- if (isRecord(headers)) {
454
+ if (isRecord$1(headers)) {
454
455
  const raw = headers["retry-after"] ?? headers["Retry-After"];
455
456
  if (typeof raw === "string") {
456
457
  const parsed = Number.parseFloat(raw);
@@ -512,6 +513,13 @@ function classifyMSTeamsSendError(err) {
512
513
  statusCode,
513
514
  errorCode
514
515
  };
516
+ if (statusCode == null) {
517
+ const networkCode = isRecord$1(err) && typeof err.code === "string" ? err.code : null;
518
+ if (networkCode === "ECONNREFUSED" || networkCode === "ENOTFOUND" || networkCode === "EHOSTUNREACH" || networkCode === "ETIMEDOUT" || networkCode === "ECONNRESET") return {
519
+ kind: "network",
520
+ errorCode: networkCode
521
+ };
522
+ }
515
523
  return {
516
524
  kind: "unknown",
517
525
  statusCode: statusCode ?? void 0,
@@ -536,6 +544,7 @@ function formatMSTeamsSendErrorHint(classification) {
536
544
  if (classification.errorCode === "ContentStreamNotAllowed") return "Teams expired the content stream; stop streaming earlier and fall back to normal message delivery";
537
545
  if (classification.kind === "throttled") return "Teams throttled the bot; backing off may help";
538
546
  if (classification.kind === "transient") return "transient Teams/Bot Framework error; retry may succeed";
547
+ if (classification.kind === "network") return "transport-level failure sending reply to Teams Bot Connector (smba.trafficmanager.net) — check egress firewall rules allow outbound HTTPS to smba.trafficmanager.net";
539
548
  }
540
549
  //#endregion
541
550
  //#region extensions/msteams/src/user-agent.ts
@@ -617,7 +626,7 @@ function createFederatedApp(creds, sdk) {
617
626
  if (!creds.certificatePath) throw new Error("Federated credentials require either a certificate path or managed identity.");
618
627
  let privateKey;
619
628
  try {
620
- privateKey = fs$1.readFileSync(creds.certificatePath, "utf-8");
629
+ privateKey = fs.readFileSync(creds.certificatePath, "utf-8");
621
630
  } catch (err) {
622
631
  const msg = err instanceof Error ? err.message : String(err);
623
632
  throw new Error(`Failed to read certificate file at '${creds.certificatePath}': ${msg}`, { cause: err });
@@ -1045,11 +1054,23 @@ async function createBotFrameworkJwtValidator(creds) {
1045
1054
  if (!isJwtPayloadObject(verifiedPayload)) return false;
1046
1055
  if (getAudienceClaims(verifiedPayload).includes(BOT_FRAMEWORK_GLOBAL_AUDIENCE) && !hasExpectedBotIdentity(verifiedPayload, creds.appId)) return false;
1047
1056
  return true;
1048
- } catch {
1057
+ } catch (err) {
1058
+ if (isJwksNetworkError(err)) throw err;
1049
1059
  return false;
1050
1060
  }
1051
1061
  } };
1052
1062
  }
1063
+ /**
1064
+ * Return true when the error originated from a network-level failure fetching
1065
+ * the JWKS endpoint (DNS resolution, connection refused, TLS handshake, etc.)
1066
+ * rather than from token verification logic.
1067
+ */
1068
+ function isJwksNetworkError(err) {
1069
+ if (!(err instanceof Error)) return false;
1070
+ const code = err.code;
1071
+ if (code === "ECONNREFUSED" || code === "ENOTFOUND" || code === "EHOSTUNREACH" || code === "ETIMEDOUT" || code === "ECONNRESET") return true;
1072
+ return /jwks|key fetch|getSigningKey/i.test(err.message) && /network|fetch|connect/i.test(err.message);
1073
+ }
1053
1074
  //#endregion
1054
1075
  //#region extensions/msteams/src/token-response.ts
1055
1076
  function readAccessToken(value) {
@@ -1135,8 +1156,7 @@ function loadDelegatedTokens() {
1135
1156
  }
1136
1157
  function saveDelegatedTokens(tokens) {
1137
1158
  const tokenPath = resolveDelegatedTokenPath();
1138
- mkdirSync(dirname(tokenPath), { recursive: true });
1139
- writeFileSync(tokenPath, JSON.stringify(tokens, null, 2), "utf8");
1159
+ privateFileStoreSync(dirname(tokenPath)).writeJson(basename(tokenPath), tokens);
1140
1160
  }
1141
1161
  async function resolveDelegatedAccessToken(params) {
1142
1162
  const tokens = loadDelegatedTokens();
@@ -1351,4 +1371,4 @@ async function searchGraphUsers(params) {
1351
1371
  })).value ?? [];
1352
1372
  }
1353
1373
  //#endregion
1354
- export { ATTACHMENT_TAG_RE as A, isLikelyImageAttachment as B, loadMSTeamsSdkWithAuth as C, formatMSTeamsSendErrorHint as D, classifyMSTeamsSendError as E, estimateBase64DecodedBytes as F, resolveAttachmentFetchPolicy as G, isUrlAllowed as H, extractHtmlFromAttachment as I, safeFetchWithPolicy as J, resolveMediaSsrfPolicy as K, extractInlineImageCandidates as L, IMG_SRC_RE as M, applyAuthorizationHeaderForUrl as N, formatUnknownError as O, encodeGraphShareId as P, inferPlaceholder as R, createMSTeamsTokenProvider as S, ensureUserAgentHeader as T, normalizeContentType as U, isRecord$1 as V, readNestedString as W, tryBuildGraphSharesUrlForSharedLink as X, safeHostForUrl as Y, resolveMSTeamsStorePath as _, fetchGraphJson as a, createBotFrameworkJwtValidator as b, normalizeQuery as c, postGraphJson as d, resolveGraphToken as f, saveDelegatedTokens as g, resolveMSTeamsCredentials as h, fetchGraphAbsoluteUrl as i, GRAPH_ROOT as j, isRevokedProxyError as k, patchGraphJson as l, loadDelegatedTokens as m, deleteGraphRequest as n, listChannelsForTeam as o, hasConfiguredMSTeamsCredentials as p, resolveRequestUrl as q, escapeOData as r, listTeamsByName as s, searchGraphUsers as t, postGraphBetaJson as u, normalizeSecretInputString as v, buildUserAgent as w, createMSTeamsAdapter as x, readAccessToken as y, isDownloadableAttachment as z };
1374
+ export { ATTACHMENT_TAG_RE as A, isLikelyImageAttachment as B, loadMSTeamsSdkWithAuth as C, formatMSTeamsSendErrorHint as D, classifyMSTeamsSendError as E, estimateBase64DecodedBytes as F, resolveAttachmentFetchPolicy as G, isUrlAllowed as H, extractHtmlFromAttachment as I, safeFetchWithPolicy as J, resolveMediaSsrfPolicy as K, extractInlineImageCandidates as L, IMG_SRC_RE as M, applyAuthorizationHeaderForUrl as N, formatUnknownError as O, encodeGraphShareId as P, inferPlaceholder as R, createMSTeamsTokenProvider as S, ensureUserAgentHeader as T, normalizeContentType as U, isRecord$2 as V, readNestedString as W, tryBuildGraphSharesUrlForSharedLink as X, safeHostForUrl as Y, resolveMSTeamsStorePath as _, fetchGraphJson as a, createBotFrameworkJwtValidator as b, normalizeQuery as c, postGraphJson as d, resolveGraphToken as f, saveDelegatedTokens as g, resolveMSTeamsCredentials as h, fetchGraphAbsoluteUrl as i, GRAPH_ROOT as j, isRevokedProxyError as k, patchGraphJson as l, loadDelegatedTokens as m, deleteGraphRequest as n, listChannelsForTeam as o, hasConfiguredMSTeamsCredentials as p, resolveRequestUrl as q, escapeOData as r, listTeamsByName as s, searchGraphUsers as t, postGraphBetaJson as u, normalizeSecretInputString as v, buildUserAgent as w, createMSTeamsAdapter as x, readAccessToken as y, isDownloadableAttachment as z };
@@ -1,4 +1,4 @@
1
- import { C as normalizeChannelSlug, D as resolveChannelEntryMatchWithFallback, E as resolveAllowlistMatchSimple, M as resolveNestedAllowlistDecision, P as resolveToolsBySender, i as buildChannelKeyCandidates, p as evaluateSenderGroupAccessForPolicy, v as isDangerousNameMatchingEnabled } from "./runtime-api-DV1iVMn1.js";
1
+ import { O as resolveNestedAllowlistDecision, S as normalizeChannelSlug, T as resolveChannelEntryMatchWithFallback, _ as isDangerousNameMatchingEnabled, i as buildChannelKeyCandidates, k as resolveToolsBySender, w as resolveAllowlistMatchSimple } from "./runtime-api-C3EIaIpt.js";
2
2
  //#region extensions/msteams/src/policy.ts
3
3
  function resolveMSTeamsRouteConfig(params) {
4
4
  const teamId = params.teamId?.trim();
@@ -130,13 +130,5 @@ function resolveMSTeamsReplyPolicy(params) {
130
130
  replyStyle: params.channelConfig?.replyStyle ?? params.teamConfig?.replyStyle ?? params.globalConfig?.replyStyle ?? (requireMention ? "thread" : "top-level")
131
131
  };
132
132
  }
133
- function isMSTeamsGroupAllowed(params) {
134
- return evaluateSenderGroupAccessForPolicy({
135
- groupPolicy: params.groupPolicy,
136
- groupAllowFrom: params.allowFrom.map((entry) => String(entry)),
137
- senderId: params.senderId,
138
- isSenderAllowed: () => resolveMSTeamsAllowlistMatch(params).allowed
139
- }).allowed;
140
- }
141
133
  //#endregion
142
- export { resolveMSTeamsRouteConfig as a, resolveMSTeamsReplyPolicy as i, resolveMSTeamsAllowlistMatch as n, resolveMSTeamsGroupToolPolicy as r, isMSTeamsGroupAllowed as t };
134
+ export { resolveMSTeamsRouteConfig as i, resolveMSTeamsGroupToolPolicy as n, resolveMSTeamsReplyPolicy as r, resolveMSTeamsAllowlistMatch as t };
@@ -1,11 +1,14 @@
1
- import { L as getMSTeamsRuntime, O as resolveChannelMediaMaxBytes, _ as getFileExtension, b as loadOutboundMediaFromUrl, d as detectMime, h as extractOriginalFilename, m as extensionForMime, w as normalizeStringEntries } from "./runtime-api-DV1iVMn1.js";
2
- import { C as loadMSTeamsSdkWithAuth, D as formatMSTeamsSendErrorHint, E as classifyMSTeamsSendError, O as formatUnknownError, S as createMSTeamsTokenProvider, _ as resolveMSTeamsStorePath, h as resolveMSTeamsCredentials, k as isRevokedProxyError, m as loadDelegatedTokens, w as buildUserAgent, x as createMSTeamsAdapter, y as readAccessToken } from "./graph-users-9uQJepqr.js";
3
- import { convertMarkdownTables, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, sleep } from "openclaw/plugin-sdk/text-runtime";
1
+ import { C as normalizeStringEntries, E as resolveChannelMediaMaxBytes, M as getMSTeamsRuntime, d as detectMime, g as getFileExtension, m as extractOriginalFilename, p as extensionForMime, y as loadOutboundMediaFromUrl } from "./runtime-api-C3EIaIpt.js";
2
+ import { C as loadMSTeamsSdkWithAuth, D as formatMSTeamsSendErrorHint, E as classifyMSTeamsSendError, O as formatUnknownError, S as createMSTeamsTokenProvider, _ as resolveMSTeamsStorePath, h as resolveMSTeamsCredentials, k as isRevokedProxyError, m as loadDelegatedTokens, w as buildUserAgent, x as createMSTeamsAdapter, y as readAccessToken } from "./graph-users-CCU0WVMZ.js";
3
+ import { i as resolveMSTeamsRouteConfig, r as resolveMSTeamsReplyPolicy } from "./policy-bM71GXRd.js";
4
+ import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-message";
5
+ import { convertMarkdownTables, isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, sleep } from "openclaw/plugin-sdk/text-runtime";
4
6
  import { withFileLock } from "openclaw/plugin-sdk/file-lock";
5
7
  import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
6
8
  import { lookup } from "node:dns/promises";
7
- import fs from "node:fs";
9
+ import { isPrivateIpAddress } from "openclaw/plugin-sdk/ssrf-policy";
8
10
  import path from "node:path";
11
+ import { pathExists } from "openclaw/plugin-sdk/security-runtime";
9
12
  import { readJsonFileWithFallback, writeJsonFileAtomically } from "openclaw/plugin-sdk/json-store";
10
13
  import crypto from "node:crypto";
11
14
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
@@ -72,11 +75,7 @@ async function writeJsonFile(filePath, value) {
72
75
  await writeJsonFileAtomically(filePath, value);
73
76
  }
74
77
  async function ensureJsonFile(filePath, fallback) {
75
- try {
76
- await fs.promises.access(filePath);
77
- } catch {
78
- await writeJsonFile(filePath, fallback);
79
- }
78
+ if (!await pathExists(filePath)) await writeJsonFile(filePath, fallback);
80
79
  }
81
80
  async function withFileLock$1(filePath, fallback, fn) {
82
81
  await ensureJsonFile(filePath, fallback);
@@ -182,14 +181,6 @@ function createMSTeamsConversationStoreFs(params) {
182
181
  const STORE_FILENAME$1 = "msteams-polls.json";
183
182
  const MAX_POLLS = 1e3;
184
183
  const POLL_TTL_MS = 720 * 60 * 60 * 1e3;
185
- function isRecord(value) {
186
- return typeof value === "object" && value !== null && !Array.isArray(value);
187
- }
188
- function normalizeOptionalString$1(value) {
189
- if (typeof value !== "string") return;
190
- const trimmed = value.trim();
191
- return trimmed ? trimmed : void 0;
192
- }
193
184
  function normalizeChoiceValue(value) {
194
185
  if (typeof value === "string") {
195
186
  const trimmed = value.trim();
@@ -214,7 +205,7 @@ function readNestedValue(value, keys) {
214
205
  return current;
215
206
  }
216
207
  function readNestedString(value, keys) {
217
- return normalizeOptionalString$1(readNestedValue(value, keys));
208
+ return normalizeOptionalString(readNestedValue(value, keys));
218
209
  }
219
210
  function extractMSTeamsPollVote(activity) {
220
211
  const value = activity?.value;
@@ -395,9 +386,6 @@ function createMSTeamsPollStoreFs(params) {
395
386
  * - Building FileInfoCard attachments (to confirm upload completion)
396
387
  * - Parsing fileConsent/invoke activities
397
388
  */
398
- function normalizeLowercaseStringOrEmpty$1(value) {
399
- return typeof value === "string" ? value.trim().toLowerCase() : "";
400
- }
401
389
  /**
402
390
  * Allowlist of domains that are valid targets for file consent uploads.
403
391
  * These are the Microsoft/SharePoint domains that Teams legitimately provides
@@ -418,31 +406,10 @@ const CONSENT_UPLOAD_HOST_ALLOWLIST = [
418
406
  "graph.microsoft.cn"
419
407
  ];
420
408
  /**
421
- * Returns true if the given IPv4 or IPv6 address is in a private, loopback,
422
- * or link-local range that must never be reached via consent uploads.
409
+ * Returns true if the given IPv4 or IPv6 address is private, internal, or
410
+ * special-use and must never be reached via consent uploads.
423
411
  */
424
- function isPrivateOrReservedIP(ip) {
425
- const ipv4MappedMatch = /^::ffff:(\d+\.\d+\.\d+\.\d+)$/i.exec(ip);
426
- if (ipv4MappedMatch) return isPrivateOrReservedIP(ipv4MappedMatch[1]);
427
- const v4Parts = ip.split(".");
428
- if (v4Parts.length === 4) {
429
- const octets = v4Parts.map(Number);
430
- if (octets.some((n) => !Number.isInteger(n) || n < 0 || n > 255)) return false;
431
- const [a, b] = octets;
432
- if (a === 10) return true;
433
- if (a === 172 && b >= 16 && b <= 31) return true;
434
- if (a === 192 && b === 168) return true;
435
- if (a === 127) return true;
436
- if (a === 169 && b === 254) return true;
437
- if (a === 0) return true;
438
- }
439
- const normalized = normalizeLowercaseStringOrEmpty$1(ip);
440
- if (normalized === "::1") return true;
441
- if (normalized.startsWith("fe80:") || normalized.startsWith("fe80")) return true;
442
- if (normalized.startsWith("fc") || normalized.startsWith("fd")) return true;
443
- if (normalized === "::") return true;
444
- return false;
445
- }
412
+ const isPrivateOrReservedIP = isPrivateIpAddress;
446
413
  /**
447
414
  * Validate that a consent upload URL is safe to PUT to.
448
415
  * Checks:
@@ -460,7 +427,7 @@ async function validateConsentUploadUrl(url, opts) {
460
427
  throw new Error("Consent upload URL is not a valid URL");
461
428
  }
462
429
  if (parsed.protocol !== "https:") throw new Error(`Consent upload URL must use HTTPS, got ${parsed.protocol}`);
463
- const hostname = normalizeLowercaseStringOrEmpty$1(parsed.hostname);
430
+ const hostname = normalizeLowercaseStringOrEmpty(parsed.hostname);
464
431
  if (!(opts?.allowlist ?? CONSENT_UPLOAD_HOST_ALLOWLIST).some((entry) => hostname === entry || hostname.endsWith(`.${entry}`))) throw new Error(`Consent upload URL hostname "${hostname}" is not in the allowed domains`);
465
432
  const resolveFn = opts?.resolveFn ?? ((name) => lookup(name, { all: true }));
466
433
  let resolved;
@@ -1554,7 +1521,7 @@ async function sendMSTeamsMessages(params) {
1554
1521
  const resolvedThreadId = params.conversationRef.threadId ?? params.conversationRef.activityId;
1555
1522
  if (params.replyStyle === "thread") {
1556
1523
  const ctx = params.context;
1557
- if (!ctx) throw new Error("Missing context for replyStyle=thread");
1524
+ if (!ctx) return await sendProactively(messages, 0, resolvedThreadId);
1558
1525
  const messageIds = [];
1559
1526
  for (const [idx, message] of messages.entries()) {
1560
1527
  const result = await withRevokedProxyFallback({
@@ -1579,6 +1546,23 @@ async function sendMSTeamsMessages(params) {
1579
1546
  }
1580
1547
  //#endregion
1581
1548
  //#region extensions/msteams/src/send-context.ts
1549
+ function resolveMSTeamsProactiveReplyStyle(params) {
1550
+ const threadRootId = params.ref.threadId ?? params.ref.activityId;
1551
+ if (params.conversationType !== "channel" || !threadRootId) return "top-level";
1552
+ const routeConfig = resolveMSTeamsRouteConfig({
1553
+ cfg: params.cfg,
1554
+ teamId: params.ref.teamId,
1555
+ conversationId: params.conversationId,
1556
+ allowNameMatching: false
1557
+ });
1558
+ const { replyStyle } = resolveMSTeamsReplyPolicy({
1559
+ isDirectMessage: false,
1560
+ globalConfig: params.cfg,
1561
+ teamConfig: routeConfig.teamConfig,
1562
+ channelConfig: routeConfig.channelConfig
1563
+ });
1564
+ return replyStyle;
1565
+ }
1582
1566
  /**
1583
1567
  * Parse the target value into a conversation reference lookup key.
1584
1568
  * Supported formats:
@@ -1646,6 +1630,12 @@ async function resolveMSTeamsSendContext(params) {
1646
1630
  if (storedConversationType === "personal") conversationType = "personal";
1647
1631
  else if (storedConversationType === "channel") conversationType = "channel";
1648
1632
  else conversationType = "groupChat";
1633
+ const replyStyle = resolveMSTeamsProactiveReplyStyle({
1634
+ cfg: msteamsCfg,
1635
+ conversationId,
1636
+ ref,
1637
+ conversationType
1638
+ });
1649
1639
  const sharePointSiteId = msteamsCfg.sharePointSiteId;
1650
1640
  const mediaMaxBytes = resolveChannelMediaMaxBytes({
1651
1641
  cfg: params.cfg,
@@ -1678,6 +1668,7 @@ async function resolveMSTeamsSendContext(params) {
1678
1668
  adapter,
1679
1669
  log,
1680
1670
  conversationType,
1671
+ replyStyle,
1681
1672
  tokenProvider,
1682
1673
  sharePointSiteId,
1683
1674
  mediaMaxBytes,
@@ -1693,6 +1684,29 @@ const FILE_CONSENT_THRESHOLD_BYTES = 4 * 1024 * 1024;
1693
1684
  * Higher than the default because OneDrive upload handles large files well.
1694
1685
  */
1695
1686
  const MSTEAMS_MAX_MEDIA_BYTES = 100 * 1024 * 1024;
1687
+ function createMSTeamsSendReceipt(params) {
1688
+ return createMessageReceiptFromOutboundResults({
1689
+ kind: params.kind,
1690
+ results: params.platformMessageIds.map((messageId) => ({
1691
+ channel: "msteams",
1692
+ messageId,
1693
+ conversationId: params.conversationId
1694
+ }))
1695
+ });
1696
+ }
1697
+ function createMSTeamsSendResult(params) {
1698
+ const platformMessageIds = (params.platformMessageIds?.length ? [...params.platformMessageIds] : [params.messageId]).map((messageId) => messageId.trim()).filter((messageId) => messageId && messageId !== "unknown");
1699
+ return {
1700
+ messageId: params.messageId,
1701
+ conversationId: params.conversationId,
1702
+ receipt: createMSTeamsSendReceipt({
1703
+ conversationId: params.conversationId,
1704
+ platformMessageIds,
1705
+ kind: params.kind
1706
+ }),
1707
+ ...params.pendingUploadId ? { pendingUploadId: params.pendingUploadId } : {}
1708
+ };
1709
+ }
1696
1710
  /**
1697
1711
  * Send a message to a Teams conversation or user.
1698
1712
  *
@@ -1774,11 +1788,12 @@ async function sendMessageMSTeams(params) {
1774
1788
  messageId,
1775
1789
  uploadId
1776
1790
  });
1777
- return {
1791
+ return createMSTeamsSendResult({
1778
1792
  messageId,
1779
1793
  conversationId,
1794
+ kind: "card",
1780
1795
  pendingUploadId: uploadId
1781
- };
1796
+ });
1782
1797
  }
1783
1798
  if (conversationType === "personal") {
1784
1799
  const base64 = media.buffer.toString("base64");
@@ -1833,10 +1848,11 @@ async function sendMessageMSTeams(params) {
1833
1848
  messageId,
1834
1849
  fileName: driveItem.name
1835
1850
  });
1836
- return {
1851
+ return createMSTeamsSendResult({
1837
1852
  messageId,
1838
- conversationId
1839
- };
1853
+ conversationId,
1854
+ kind: "media"
1855
+ });
1840
1856
  }
1841
1857
  log.debug?.("uploading to OneDrive (no SharePoint site configured)", {
1842
1858
  fileName,
@@ -1867,10 +1883,11 @@ async function sendMessageMSTeams(params) {
1867
1883
  messageId,
1868
1884
  shareUrl: uploaded.shareUrl
1869
1885
  });
1870
- return {
1886
+ return createMSTeamsSendResult({
1871
1887
  messageId,
1872
- conversationId
1873
- };
1888
+ conversationId,
1889
+ kind: "media"
1890
+ });
1874
1891
  } catch (err) {
1875
1892
  const classification = classifyMSTeamsSendError(err);
1876
1893
  const hint = formatMSTeamsSendErrorHint(classification);
@@ -1884,11 +1901,11 @@ async function sendMessageMSTeams(params) {
1884
1901
  * Send a text message with optional base64 media URL.
1885
1902
  */
1886
1903
  async function sendTextWithMedia(ctx, text, mediaUrl) {
1887
- const { adapter, appId, conversationId, ref, log, tokenProvider, sharePointSiteId, mediaMaxBytes } = ctx;
1888
- let messageIds;
1904
+ const { adapter, appId, conversationId, ref, log, tokenProvider, sharePointSiteId, mediaMaxBytes, replyStyle } = ctx;
1905
+ let platformMessageIds;
1889
1906
  try {
1890
- messageIds = await sendMSTeamsMessages({
1891
- replyStyle: "top-level",
1907
+ platformMessageIds = await sendMSTeamsMessages({
1908
+ replyStyle,
1892
1909
  adapter,
1893
1910
  appId,
1894
1911
  conversationRef: ref,
@@ -1913,14 +1930,19 @@ async function sendTextWithMedia(ctx, text, mediaUrl) {
1913
1930
  const status = classification.statusCode ? ` (HTTP ${classification.statusCode})` : "";
1914
1931
  throw new Error(`msteams send failed${status}: ${formatUnknownError(err)}${hint ? ` (${hint})` : ""}`, { cause: err });
1915
1932
  }
1916
- const messageId = messageIds[0] ?? "unknown";
1933
+ const messageId = platformMessageIds[0] ?? "unknown";
1917
1934
  log.info("sent proactive message", {
1918
1935
  conversationId,
1919
1936
  messageId
1920
1937
  });
1921
1938
  return {
1922
1939
  messageId,
1923
- conversationId
1940
+ conversationId,
1941
+ receipt: createMSTeamsSendReceipt({
1942
+ conversationId,
1943
+ platformMessageIds,
1944
+ kind: mediaUrl ? "media" : "text"
1945
+ })
1924
1946
  };
1925
1947
  }
1926
1948
  async function sendProactiveActivityRaw({ adapter, appId, ref, activity }) {
@@ -1,4 +1,4 @@
1
- import { c as normalizeQuery, f as resolveGraphToken, o as listChannelsForTeam, s as listTeamsByName, t as searchGraphUsers } from "./graph-users-9uQJepqr.js";
1
+ import { c as normalizeQuery, f as resolveGraphToken, o as listChannelsForTeam, s as listTeamsByName, t as searchGraphUsers } from "./graph-users-CCU0WVMZ.js";
2
2
  import { mapAllowlistResolutionInputs } from "openclaw/plugin-sdk/allow-from";
3
3
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime";
4
4
  //#region extensions/msteams/src/resolve-allowlist.ts
@@ -1,9 +1,9 @@
1
1
  import { mergeAllowlist, resolveAllowlistMatchSimple, summarizeMapping } from "openclaw/plugin-sdk/allow-from";
2
+ import { createChannelMessageReplyPipeline } from "openclaw/plugin-sdk/channel-message";
2
3
  import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pairing";
3
- import { evaluateSenderGroupAccessForPolicy, readStoreAllowFromForDmPolicy, resolveDmGroupAccessWithLists, resolveEffectiveAllowFromLists, resolveSenderScopedGroupPolicy, resolveToolsBySender } from "openclaw/plugin-sdk/channel-policy";
4
+ import { resolveToolsBySender } from "openclaw/plugin-sdk/channel-policy";
4
5
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
5
6
  import { logTypingFailure } from "openclaw/plugin-sdk/channel-logging";
6
- import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
7
7
  import { PAIRING_APPROVED_MESSAGE, buildProbeChannelStatusSummary, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/channel-status";
8
8
  import { buildChannelKeyCandidates, normalizeChannelSlug, resolveChannelEntryMatchWithFallback, resolveNestedAllowlistDecision } from "openclaw/plugin-sdk/channel-targets";
9
9
  import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
@@ -25,4 +25,4 @@ const { setRuntime: setMSTeamsRuntime, getRuntime: getMSTeamsRuntime, tryGetRunt
25
25
  errorMessage: "MSTeams runtime not initialized"
26
26
  });
27
27
  //#endregion
28
- export { resolveDmGroupAccessWithLists as A, normalizeChannelSlug as C, resolveChannelEntryMatchWithFallback as D, resolveAllowlistMatchSimple as E, summarizeMapping as F, withFileLock$1 as I, getMSTeamsRuntime as L, resolveNestedAllowlistDecision as M, resolveSenderScopedGroupPolicy as N, resolveChannelMediaMaxBytes as O, resolveToolsBySender as P, getOptionalMSTeamsRuntime as R, mergeAllowlist as S, readStoreAllowFromForDmPolicy as T, getFileExtension as _, buildMediaPayload as a, loadOutboundMediaFromUrl as b, createChannelPairingController as c, detectMime as d, dispatchReplyFromConfigWithSettledDispatcher$1 as f, fetchWithSsrFGuard$1 as g, extractOriginalFilename as h, buildChannelKeyCandidates as i, resolveEffectiveAllowFromLists as j, resolveDefaultGroupPolicy as k, createChannelReplyPipeline as l, extensionForMime as m, DEFAULT_WEBHOOK_MAX_BODY_BYTES as n, buildProbeChannelStatusSummary as o, evaluateSenderGroupAccessForPolicy as p, PAIRING_APPROVED_MESSAGE as r, chunkTextForOutbound as s, DEFAULT_ACCOUNT_ID as t, createDefaultChannelRuntimeState as u, isDangerousNameMatchingEnabled as v, normalizeStringEntries as w, logTypingFailure as x, keepHttpServerTaskAlive as y, setMSTeamsRuntime as z };
28
+ export { summarizeMapping as A, normalizeStringEntries as C, resolveDefaultGroupPolicy as D, resolveChannelMediaMaxBytes as E, getMSTeamsRuntime as M, getOptionalMSTeamsRuntime as N, resolveNestedAllowlistDecision as O, setMSTeamsRuntime as P, normalizeChannelSlug as S, resolveChannelEntryMatchWithFallback as T, isDangerousNameMatchingEnabled as _, buildMediaPayload as a, logTypingFailure as b, createChannelMessageReplyPipeline as c, detectMime as d, dispatchReplyFromConfigWithSettledDispatcher$1 as f, getFileExtension as g, fetchWithSsrFGuard$1 as h, buildChannelKeyCandidates as i, withFileLock$1 as j, resolveToolsBySender as k, createChannelPairingController as l, extractOriginalFilename as m, DEFAULT_WEBHOOK_MAX_BODY_BYTES as n, buildProbeChannelStatusSummary as o, extensionForMime as p, PAIRING_APPROVED_MESSAGE as r, chunkTextForOutbound as s, DEFAULT_ACCOUNT_ID as t, createDefaultChannelRuntimeState as u, keepHttpServerTaskAlive as v, resolveAllowlistMatchSimple as w, mergeAllowlist as x, loadOutboundMediaFromUrl as y };