@openclaw/msteams 2026.6.33 → 2026.6.35

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-De7IU_NC.js";
2
- import { c as msteamsSetupAdapter, n as openDelegatedOAuthUrl, s as createMSTeamsSetupWizardBase, t as msteamsSetupWizard } from "./setup-surface-CuIeEFrR.js";
1
+ import { t as msteamsPlugin } from "./channel-B6jPI4WB.js";
2
+ import { c as msteamsSetupAdapter, n as openDelegatedOAuthUrl, s as createMSTeamsSetupWizardBase, t as msteamsSetupWizard } from "./setup-surface-CcfpPwaZ.js";
3
3
  export { createMSTeamsSetupWizardBase, msteamsPlugin, msteamsSetupAdapter, msteamsSetupWizard, openDelegatedOAuthUrl };
@@ -1,7 +1,7 @@
1
1
  import { DEFAULT_ACCOUNT_ID, PAIRING_APPROVED_MESSAGE, buildChannelKeyCandidates, buildProbeChannelStatusSummary, chunkTextForOutbound, createDefaultChannelRuntimeState, isDangerousNameMatchingEnabled, normalizeChannelSlug, resolveAllowlistMatchSimple, resolveChannelEntryMatchWithFallback, resolveNestedAllowlistDecision, resolveToolsBySender } from "./runtime-api.js";
2
- import { C as resolveMSTeamsCredentials, a as parseMSTeamsTeamChannelInput, c as resolveMSTeamsUserAllowlist, i as parseMSTeamsConversationId, n as normalizeMSTeamsMessagingTarget, r as normalizeMSTeamsUserInput, s as resolveMSTeamsChannelAllowlist, t as looksLikeMSTeamsTargetId } from "./resolve-allowlist-DlH_aNya.js";
2
+ import { C as resolveMSTeamsCredentials, a as parseMSTeamsTeamChannelInput, c as resolveMSTeamsUserAllowlist, i as parseMSTeamsConversationId, n as normalizeMSTeamsMessagingTarget, r as normalizeMSTeamsUserInput, s as resolveMSTeamsChannelAllowlist, t as looksLikeMSTeamsTargetId } from "./resolve-allowlist-BG4l6eoi.js";
3
3
  import { t as MSTeamsChannelConfigSchema } from "./config-schema-BL4qQZiA.js";
4
- import { c as msteamsSetupAdapter, t as msteamsSetupWizard } from "./setup-surface-CuIeEFrR.js";
4
+ import { c as msteamsSetupAdapter, t as msteamsSetupWizard } from "./setup-surface-CcfpPwaZ.js";
5
5
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
6
6
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
7
7
  import { createTopLevelChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
@@ -336,7 +336,7 @@ const collectMSTeamsSecurityWarnings = createAllowlistProviderGroupPolicyWarning
336
336
  resolveGroupPolicy: ({ cfg }) => cfg.channels?.msteams?.groupPolicy,
337
337
  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."] : []
338
338
  });
339
- const loadMSTeamsChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-DNzD6A6c.js"), "msTeamsChannelRuntime");
339
+ const loadMSTeamsChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-CVzTPYpe.js"), "msTeamsChannelRuntime");
340
340
  const resolveMSTeamsChannelConfig = (cfg) => ({
341
341
  allowFrom: cfg.channels?.msteams?.allowFrom,
342
342
  defaultTo: cfg.channels?.msteams?.defaultTo
@@ -1131,7 +1131,7 @@ const msteamsPlugin = createChatChannelPlugin({
1131
1131
  })
1132
1132
  }),
1133
1133
  gateway: { startAccount: async (ctx) => {
1134
- const { monitorMSTeamsProvider } = await import("./src-_fXCY2NI.js");
1134
+ const { monitorMSTeamsProvider } = await import("./src-KIhjJ_ma.js");
1135
1135
  const port = ctx.cfg.channels?.msteams?.webhook?.port ?? 3978;
1136
1136
  ctx.setStatus({
1137
1137
  accountId: ctx.accountId,
@@ -1,2 +1,2 @@
1
- import { t as msteamsPlugin } from "./channel-De7IU_NC.js";
1
+ import { t as msteamsPlugin } from "./channel-B6jPI4WB.js";
2
2
  export { msteamsPlugin };
@@ -1,8 +1,8 @@
1
1
  import { chunkTextForOutbound, normalizeStringEntries as normalizeStringEntries$1 } from "./runtime-api.js";
2
- import { _ as patchGraphJson, b as resolveGraphToken, d as escapeOData, f as fetchGraphAbsoluteUrl, g as normalizeQuery, h as listTeamsByName, l as searchGraphUsers, m as listChannelsForTeam, p as fetchGraphJson, u as deleteGraphRequest, v as postGraphBetaJson, y as postGraphJson } from "./resolve-allowlist-DlH_aNya.js";
3
- import { n as MSTEAMS_PRESENTATION_CAPABILITIES, r as buildMSTeamsPresentationCard } from "./channel-De7IU_NC.js";
2
+ import { _ as patchGraphJson, b as resolveGraphToken, d as escapeOData, f as fetchGraphAbsoluteUrl, g as normalizeQuery, h as listTeamsByName, l as searchGraphUsers, m as listChannelsForTeam, p as fetchGraphJson, u as deleteGraphRequest, v as postGraphBetaJson, y as postGraphJson } from "./resolve-allowlist-BG4l6eoi.js";
3
+ import { n as MSTEAMS_PRESENTATION_CAPABILITIES, r as buildMSTeamsPresentationCard } from "./channel-B6jPI4WB.js";
4
4
  import { l as createMSTeamsPollStoreState, v as createMSTeamsConversationStoreState } from "./polls-C1VgSvKE.js";
5
- import { a as sendMessageMSTeams, i as sendAdaptiveCardMSTeams, n as deleteMessageMSTeams, o as sendPollMSTeams, r as editMessageMSTeams, t as probeMSTeams } from "./probe-BrPEeWJe.js";
5
+ import { a as sendMessageMSTeams, i as sendAdaptiveCardMSTeams, n as deleteMessageMSTeams, o as sendPollMSTeams, r as editMessageMSTeams, t as probeMSTeams } from "./probe-tSXvGIGv.js";
6
6
  import { resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-outbound";
7
7
  import { normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { resolvePayloadMediaUrls, resolveTextChunksWithFallback, sendPayloadMediaSequence } from "openclaw/plugin-sdk/reply-payload";
@@ -1,4 +1,4 @@
1
- import { C as resolveMSTeamsCredentials, n as normalizeMSTeamsMessagingTarget } from "./resolve-allowlist-DlH_aNya.js";
1
+ import { C as resolveMSTeamsCredentials, n as normalizeMSTeamsMessagingTarget } from "./resolve-allowlist-BG4l6eoi.js";
2
2
  import { listDirectoryEntriesFromSources } from "openclaw/plugin-sdk/directory-runtime";
3
3
  const msteamsDirectoryContractPlugin = {
4
4
  id: "msteams",
@@ -1,4 +1,4 @@
1
- import { A as MSTEAMS_OAUTH_REDIRECT_URI, D as MSTEAMS_DEFAULT_DELEGATED_SCOPES, E as exchangeMSTeamsCodeForTokens, O as MSTEAMS_OAUTH_CALLBACK_PATH, j as buildMSTeamsAuthEndpoint, k as MSTEAMS_OAUTH_CALLBACK_PORT } from "./resolve-allowlist-DlH_aNya.js";
1
+ import { A as MSTEAMS_OAUTH_REDIRECT_URI, D as MSTEAMS_DEFAULT_DELEGATED_SCOPES, E as exchangeMSTeamsCodeForTokens, O as MSTEAMS_OAUTH_CALLBACK_PATH, j as buildMSTeamsAuthEndpoint, k as MSTEAMS_OAUTH_CALLBACK_PORT } from "./resolve-allowlist-BG4l6eoi.js";
2
2
  import { generateHexPkceVerifierChallenge } from "openclaw/plugin-sdk/provider-auth";
3
3
  import { generateOAuthState, parseOAuthCallbackInput, waitForLocalOAuthCallback } from "openclaw/plugin-sdk/provider-auth-runtime";
4
4
  import { isWSL2Sync } from "openclaw/plugin-sdk/runtime-env";
@@ -1,8 +1,8 @@
1
1
  import { t as getMSTeamsRuntime } from "./runtime-BS5AZrKK.js";
2
2
  import { detectMime, extensionForMime, extractOriginalFilename, getFileExtension, loadOutboundMediaFromUrl, normalizeStringEntries as normalizeStringEntries$1, resolveChannelMediaMaxBytes } from "./runtime-api.js";
3
- import { B as normalizeBotFrameworkServiceUrl, C as resolveMSTeamsCredentials, F as loadMSTeamsSdkWithAuth, H as createMSTeamsHttpError, I as buildUserAgent, M as readAccessToken, P as createMSTeamsTokenProvider, R as describeBotFrameworkServiceUrlHost, S as loadDelegatedTokens, U as resolveMSTeamsSdkCloudOptions, W as validateMSTeamsProactiveServiceUrlBoundary, z as isAllowedBotFrameworkServiceUrl } from "./resolve-allowlist-DlH_aNya.js";
4
- import { a as resolveMSTeamsReplyPolicy, o as resolveMSTeamsRouteConfig } from "./channel-De7IU_NC.js";
5
- import { a as formatUnknownError, i as formatMSTeamsSendErrorHint, o as isRevokedProxyError, r as classifyMSTeamsSendError } from "./setup-surface-CuIeEFrR.js";
3
+ import { B as normalizeBotFrameworkServiceUrl, C as resolveMSTeamsCredentials, F as loadMSTeamsSdkWithAuth, H as createMSTeamsHttpError, I as buildUserAgent, M as readAccessToken, P as createMSTeamsTokenProvider, R as describeBotFrameworkServiceUrlHost, S as loadDelegatedTokens, U as resolveMSTeamsSdkCloudOptions, W as validateMSTeamsProactiveServiceUrlBoundary, z as isAllowedBotFrameworkServiceUrl } from "./resolve-allowlist-BG4l6eoi.js";
4
+ import { a as resolveMSTeamsReplyPolicy, o as resolveMSTeamsRouteConfig } from "./channel-B6jPI4WB.js";
5
+ import { a as formatUnknownError, i as formatMSTeamsSendErrorHint, o as isRevokedProxyError, r as classifyMSTeamsSendError } from "./setup-surface-CcfpPwaZ.js";
6
6
  import { C as toPluginJsonValue, S as resolveMSTeamsSqliteStateEnv, o as buildMSTeamsPollCard, v as createMSTeamsConversationStoreState, w as withMSTeamsSqliteMutationLock } from "./polls-C1VgSvKE.js";
7
7
  import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-outbound";
8
8
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -149,6 +149,7 @@ async function uploadToConsentUrl(params) {
149
149
  },
150
150
  body: new Uint8Array(params.buffer)
151
151
  });
152
+ await res.body?.cancel().catch(() => void 0);
152
153
  if (!res.ok) throw new Error(`File upload to consent URL failed: ${res.status} ${res.statusText}`);
153
154
  }
154
155
  //#endregion
@@ -190,9 +190,11 @@ function resolveRequestUrl(input) {
190
190
  }
191
191
  }
192
192
  function normalizeContentType(value) {
193
- if (typeof value !== "string") return;
194
- const trimmed = value.trim();
195
- return trimmed ? trimmed : void 0;
193
+ const trimmed = normalizeOptionalString(value);
194
+ if (!trimmed) return;
195
+ const parameterIndex = trimmed.indexOf(";");
196
+ if (parameterIndex === -1) return trimmed.toLowerCase();
197
+ return `${trimmed.slice(0, parameterIndex).trim().toLowerCase()}${trimmed.slice(parameterIndex)}`;
196
198
  }
197
199
  function inferPlaceholder(params) {
198
200
  const mime = normalizeLowercaseStringOrEmpty(params.contentType ?? "");
@@ -1,6 +1,6 @@
1
- import { C as resolveMSTeamsCredentials } from "./resolve-allowlist-DlH_aNya.js";
1
+ import { C as resolveMSTeamsCredentials } from "./resolve-allowlist-BG4l6eoi.js";
2
2
  import { t as MSTeamsChannelConfigSchema } from "./config-schema-BL4qQZiA.js";
3
- import { c as msteamsSetupAdapter, t as msteamsSetupWizard } from "./setup-surface-CuIeEFrR.js";
3
+ import { c as msteamsSetupAdapter, t as msteamsSetupWizard } from "./setup-surface-CcfpPwaZ.js";
4
4
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
5
5
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
6
6
  import { createTopLevelChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
@@ -1,4 +1,4 @@
1
- import { C as resolveMSTeamsCredentials, T as normalizeSecretInputString, c as resolveMSTeamsUserAllowlist, o as parseMSTeamsTeamEntry, s as resolveMSTeamsChannelAllowlist, w as saveDelegatedTokens, x as hasConfiguredMSTeamsCredentials } from "./resolve-allowlist-DlH_aNya.js";
1
+ import { C as resolveMSTeamsCredentials, T as normalizeSecretInputString, c as resolveMSTeamsUserAllowlist, o as parseMSTeamsTeamEntry, s as resolveMSTeamsChannelAllowlist, w as saveDelegatedTokens, x as hasConfiguredMSTeamsCredentials } from "./resolve-allowlist-BG4l6eoi.js";
2
2
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { asFiniteNumberInRange, parseStrictFiniteNumber } from "openclaw/plugin-sdk/number-runtime";
4
4
  import { DEFAULT_ACCOUNT_ID, createSetupTranslator, createStandardChannelSetupStatus, createTopLevelChannelAllowFromSetter, createTopLevelChannelDmPolicy, createTopLevelChannelGroupPolicySetter, mergeAllowFromEntries, splitSetupEntries } from "openclaw/plugin-sdk/setup";
@@ -449,7 +449,7 @@ const msteamsSetupWizard = {
449
449
  }
450
450
  };
451
451
  try {
452
- const { loginMSTeamsDelegated } = await import("./oauth-CKGUl-St.js");
452
+ const { loginMSTeamsDelegated } = await import("./oauth-DzLO3Jjk.js");
453
453
  const progress = params.prompter.progress(t("wizard.msteams.delegatedOAuthProgress"));
454
454
  saveDelegatedTokens(await loginMSTeamsDelegated({
455
455
  isRemote: true,
@@ -1,11 +1,11 @@
1
1
  import { n as getOptionalMSTeamsRuntime, t as getMSTeamsRuntime } from "./runtime-BS5AZrKK.js";
2
2
  import { DEFAULT_ACCOUNT_ID, DEFAULT_WEBHOOK_MAX_BODY_BYTES, buildMediaPayload, createChannelMessageReplyPipeline, createChannelPairingController, dispatchReplyFromConfigWithSettledDispatcher as dispatchReplyFromConfigWithSettledDispatcher$1, isDangerousNameMatchingEnabled, keepHttpServerTaskAlive, logTypingFailure, mergeAllowlist, resolveChannelMediaMaxBytes, resolveDefaultGroupPolicy, summarizeMapping } from "./runtime-api.js";
3
- import { $ as inferPlaceholder, C as resolveMSTeamsCredentials, F as loadMSTeamsSdkWithAuth, G as ATTACHMENT_TAG_RE, J as applyAuthorizationHeaderForUrl, K as GRAPH_ROOT, L as ensureUserAgentHeader, N as createMSTeamsExpressAdapter, P as createMSTeamsTokenProvider, Q as extractInlineImageCandidates, U as resolveMSTeamsSdkCloudOptions, V as tryNormalizeBotFrameworkServiceUrl, X as estimateBase64DecodedBytes, Y as encodeGraphShareId, Z as extractHtmlFromAttachment, at as readNestedString, c as resolveMSTeamsUserAllowlist, ct as resolveRequestUrl, dt as tryBuildGraphSharesUrlForSharedLink, et as isDownloadableAttachment, it as normalizeContentType, lt as safeFetchWithPolicy, nt as isRecord$1, ot as resolveAttachmentFetchPolicy, p as fetchGraphJson, q as IMG_SRC_RE, rt as isUrlAllowed, s as resolveMSTeamsChannelAllowlist, st as resolveMediaSsrfPolicy, tt as isLikelyImageAttachment, ut as safeHostForUrl } from "./resolve-allowlist-DlH_aNya.js";
4
- import { a as resolveMSTeamsReplyPolicy, i as resolveMSTeamsAllowlistMatch, o as resolveMSTeamsRouteConfig } from "./channel-De7IU_NC.js";
5
- import { a as formatUnknownError, i as formatMSTeamsSendErrorHint, r as classifyMSTeamsSendError } from "./setup-surface-CuIeEFrR.js";
3
+ import { $ as inferPlaceholder, C as resolveMSTeamsCredentials, F as loadMSTeamsSdkWithAuth, G as ATTACHMENT_TAG_RE, J as applyAuthorizationHeaderForUrl, K as GRAPH_ROOT, L as ensureUserAgentHeader, N as createMSTeamsExpressAdapter, P as createMSTeamsTokenProvider, Q as extractInlineImageCandidates, U as resolveMSTeamsSdkCloudOptions, V as tryNormalizeBotFrameworkServiceUrl, X as estimateBase64DecodedBytes, Y as encodeGraphShareId, Z as extractHtmlFromAttachment, at as readNestedString, c as resolveMSTeamsUserAllowlist, ct as resolveRequestUrl, dt as tryBuildGraphSharesUrlForSharedLink, et as isDownloadableAttachment, it as normalizeContentType, lt as safeFetchWithPolicy, nt as isRecord$1, ot as resolveAttachmentFetchPolicy, p as fetchGraphJson, q as IMG_SRC_RE, rt as isUrlAllowed, s as resolveMSTeamsChannelAllowlist, st as resolveMediaSsrfPolicy, tt as isLikelyImageAttachment, ut as safeHostForUrl } from "./resolve-allowlist-BG4l6eoi.js";
4
+ import { a as resolveMSTeamsReplyPolicy, i as resolveMSTeamsAllowlistMatch, o as resolveMSTeamsRouteConfig } from "./channel-B6jPI4WB.js";
5
+ import { a as formatUnknownError, i as formatMSTeamsSendErrorHint, r as classifyMSTeamsSendError } from "./setup-surface-CcfpPwaZ.js";
6
6
  import { l as createMSTeamsPollStoreState, u as extractMSTeamsPollVote, v as createMSTeamsConversationStoreState } from "./polls-C1VgSvKE.js";
7
7
  import { i as createMSTeamsSsoTokenStoreFs } from "./sso-token-store-BYZaKr82.js";
8
- import { _ as buildFileInfoCard, c as renderReplyPayloadsToMessages, d as withRevokedProxyFallback, f as resolveGraphChatId, g as removePendingUploadFs, h as getPendingUploadFs, l as sendMSTeamsMessages, m as removePendingUpload, p as getPendingUpload, s as buildConversationReference, u as sendMSTeamsActivityWithReference, v as parseFileConsentInvoke, y as uploadToConsentUrl } from "./probe-BrPEeWJe.js";
8
+ import { _ as buildFileInfoCard, c as renderReplyPayloadsToMessages, d as withRevokedProxyFallback, f as resolveGraphChatId, g as removePendingUploadFs, h as getPendingUploadFs, l as sendMSTeamsMessages, m as removePendingUpload, p as getPendingUpload, s as buildConversationReference, u as sendMSTeamsActivityWithReference, v as parseFileConsentInvoke, y as uploadToConsentUrl } from "./probe-tSXvGIGv.js";
9
9
  import { formatAllowlistMatchMeta } from "openclaw/plugin-sdk/allow-from";
10
10
  import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelProgressDraftGate, formatChannelProgressDraftText, isChannelProgressDraftWorkToolName, mergeChannelProgressDraftLine, normalizeChannelProgressDraftLineIdentity, resolveChannelPreviewStreamMode, resolveChannelProgressDraftMaxLines, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages } from "openclaw/plugin-sdk/channel-outbound";
11
11
  import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -20,6 +20,7 @@ import { resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
20
20
  import { channelIngressRoutes, resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
21
21
  import { filterSupplementalContextItems, resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
22
22
  import { DEFAULT_GROUP_HISTORY_LIMIT, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
23
+ import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
23
24
  //#region extensions/msteams/src/feedback-reflection-prompt.ts
24
25
  /** Max chars of the thumbed-down response to include in the reflection prompt. */
25
26
  const MAX_RESPONSE_CHARS = 500;
@@ -1315,6 +1316,7 @@ function buildMSTeamsMediaPayload(mediaList) {
1315
1316
  //#region extensions/msteams/src/graph-thread.ts
1316
1317
  const teamGroupIdCache = /* @__PURE__ */ new Map();
1317
1318
  const CACHE_TTL_MS = 600 * 1e3;
1319
+ const TEAM_GROUP_ID_CACHE_MAX_ENTRIES = 500;
1318
1320
  function resolveTeamGroupIdCacheExpiresAt(nowRaw = Date.now()) {
1319
1321
  const now = asDateTimestampMs(nowRaw);
1320
1322
  return now === void 0 ? void 0 : resolveExpiresAtMsFromDurationMs(CACHE_TTL_MS, { nowMs: now });
@@ -1347,10 +1349,13 @@ async function resolveTeamGroupId(token, conversationTeamId) {
1347
1349
  path: `/teams/${encodeURIComponent(conversationTeamId)}?$select=id`
1348
1350
  })).id ?? conversationTeamId;
1349
1351
  const expiresAt = resolveTeamGroupIdCacheExpiresAt();
1350
- if (expiresAt !== void 0) teamGroupIdCache.set(conversationTeamId, {
1351
- groupId,
1352
- expiresAt
1353
- });
1352
+ if (expiresAt !== void 0) {
1353
+ teamGroupIdCache.set(conversationTeamId, {
1354
+ groupId,
1355
+ expiresAt
1356
+ });
1357
+ pruneMapToMaxSize(teamGroupIdCache, TEAM_GROUP_ID_CACHE_MAX_ENTRIES);
1358
+ }
1354
1359
  return groupId;
1355
1360
  } catch {
1356
1361
  return conversationTeamId;
@@ -1527,7 +1532,7 @@ function createTeamsReplyStreamController(params) {
1527
1532
  let lastInformativeText = "";
1528
1533
  let progressLines = [];
1529
1534
  let pendingFinalPayload;
1530
- let emittedTextLength = 0;
1535
+ let emittedText = "";
1531
1536
  const wasCanceled = () => canceledLocally || Boolean(stream?.canceled);
1532
1537
  const fallbackPayloadForSuppressedFinal = (payload) => {
1533
1538
  return Boolean(payload.mediaUrl || payload.mediaUrls?.length) ? {
@@ -1567,11 +1572,20 @@ function createTeamsReplyStreamController(params) {
1567
1572
  onPartialReply(payload) {
1568
1573
  if (!stream || !payload.text || wasCanceled() || streamMode !== "partial" || streamFinalizationPending) return;
1569
1574
  const fullText = payload.text;
1570
- if (fullText.length <= emittedTextLength) return;
1571
- const delta = fullText.slice(emittedTextLength);
1575
+ let prefixLength = 0;
1576
+ while (prefixLength < emittedText.length && prefixLength < fullText.length && emittedText[prefixLength] === fullText[prefixLength]) prefixLength += 1;
1577
+ const previousRemainder = emittedText.slice(prefixLength);
1578
+ const delta = fullText.slice(prefixLength);
1579
+ if (!delta) return;
1580
+ if (previousRemainder.trim()) {
1581
+ stream.clearText();
1582
+ streamFailed = true;
1583
+ streamFinalizationPending = true;
1584
+ return;
1585
+ }
1572
1586
  try {
1573
1587
  stream.emit(delta);
1574
- emittedTextLength = fullText.length;
1588
+ emittedText = fullText;
1575
1589
  tokensEmitted = true;
1576
1590
  } catch (err) {
1577
1591
  if (isStreamCancelledError(err)) {
@@ -2230,9 +2244,7 @@ function resolveMSTeamsRouteSessionKey(params) {
2230
2244
  //#region extensions/msteams/src/monitor-handler/message-handler.ts
2231
2245
  function extractTextFromHtmlAttachments(attachments) {
2232
2246
  for (const attachment of attachments) {
2233
- if (attachment.contentType !== "text/html") continue;
2234
- const content = attachment.content;
2235
- const raw = typeof content === "string" ? content : isRecord$1(content) && typeof content.text === "string" ? content.text : isRecord$1(content) && typeof content.body === "string" ? content.body : "";
2247
+ const raw = extractHtmlFromAttachment(attachment);
2236
2248
  if (!raw) continue;
2237
2249
  const text = raw.replace(/<at[^>]*>.*?<\/at>/gis, " ").replace(/<a\b[^>]*href=["']([^"']+)["'][^>]*>(.*?)<\/a>/gis, "$2 $1").replace(/<br\s*\/?>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<[^>]+>/g, " ").replace(/&nbsp;/gi, " ").replace(/&amp;/gi, "&").replace(/\s+/g, " ").trim();
2238
2250
  if (text) return text;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@openclaw/msteams",
3
- "version": "2026.6.33",
3
+ "version": "2026.6.35",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/msteams",
9
- "version": "2026.6.33",
9
+ "version": "2026.6.35",
10
10
  "dependencies": {
11
11
  "@azure/identity": "4.13.1",
12
12
  "@microsoft/teams.api": "2.0.12",
@@ -15,7 +15,7 @@
15
15
  "typebox": "1.1.39"
16
16
  },
17
17
  "peerDependencies": {
18
- "openclaw": ">=2026.6.33"
18
+ "openclaw": ">=2026.6.35"
19
19
  },
20
20
  "peerDependenciesMeta": {
21
21
  "openclaw": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/msteams",
3
- "version": "2026.6.33",
3
+ "version": "2026.6.35",
4
4
  "description": "OpenClaw Microsoft Teams channel plugin for bot conversations.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -15,7 +15,7 @@
15
15
  "typebox": "1.1.39"
16
16
  },
17
17
  "peerDependencies": {
18
- "openclaw": ">=2026.6.33"
18
+ "openclaw": ">=2026.6.35"
19
19
  },
20
20
  "peerDependenciesMeta": {
21
21
  "openclaw": {
@@ -51,10 +51,11 @@
51
51
  "minHostVersion": ">=2026.4.10"
52
52
  },
53
53
  "compat": {
54
- "pluginApi": ">=2026.6.33"
54
+ "pluginApi": ">=2026.6.35"
55
55
  },
56
56
  "build": {
57
- "openclawVersion": "2026.6.33"
57
+ "bundledDist": false,
58
+ "openclawVersion": "2026.6.35"
58
59
  },
59
60
  "release": {
60
61
  "publishToClawHub": true,