@openclaw/msteams 2026.5.14-beta.2 → 2026.5.16-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 { i as msteamsSetupAdapter, n as openDelegatedOAuthUrl, r as createMSTeamsSetupWizardBase, t as msteamsSetupWizard } from "./setup-surface-CQrMX-nJ.js";
2
- import { t as msteamsPlugin } from "./channel-C5CVTygn.js";
1
+ import { i as msteamsSetupAdapter, n as openDelegatedOAuthUrl, r as createMSTeamsSetupWizardBase, t as msteamsSetupWizard } from "./setup-surface-CVdYNhQt.js";
2
+ import { t as msteamsPlugin } from "./channel-CQpy2Rqt.js";
3
3
  export { createMSTeamsSetupWizardBase, msteamsPlugin, msteamsSetupAdapter, msteamsSetupWizard, openDelegatedOAuthUrl };
@@ -1,6 +1,6 @@
1
1
  import { O as resolveNestedAllowlistDecision, S as normalizeChannelSlug, T as resolveChannelEntryMatchWithFallback, _ as isDangerousNameMatchingEnabled, i as buildChannelKeyCandidates, k as resolveToolsBySender, o as buildProbeChannelStatusSummary, r as PAIRING_APPROVED_MESSAGE, s as chunkTextForOutbound, t as DEFAULT_ACCOUNT_ID, u as createDefaultChannelRuntimeState, w as resolveAllowlistMatchSimple } from "./runtime-api-C3EIaIpt.js";
2
2
  import { h as resolveMSTeamsCredentials } from "./graph-users-ChPPxUzD.js";
3
- import { a as looksLikeMSTeamsTargetId, c as parseMSTeamsConversationId, d as resolveMSTeamsUserAllowlist, i as msteamsSetupAdapter, l as parseMSTeamsTeamChannelInput, o as normalizeMSTeamsMessagingTarget, s as normalizeMSTeamsUserInput, t as msteamsSetupWizard, u as resolveMSTeamsChannelAllowlist } from "./setup-surface-CQrMX-nJ.js";
3
+ import { a as looksLikeMSTeamsTargetId, c as parseMSTeamsConversationId, d as resolveMSTeamsUserAllowlist, i as msteamsSetupAdapter, l as parseMSTeamsTeamChannelInput, o as normalizeMSTeamsMessagingTarget, s as normalizeMSTeamsUserInput, t as msteamsSetupWizard, u as resolveMSTeamsChannelAllowlist } from "./setup-surface-CVdYNhQt.js";
4
4
  import { t as MSTeamsChannelConfigSchema } from "./config-schema-DwOEthCC.js";
5
5
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
6
6
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
@@ -313,7 +313,7 @@ const collectMSTeamsSecurityWarnings = createAllowlistProviderGroupPolicyWarning
313
313
  resolveGroupPolicy: ({ cfg }) => cfg.channels?.msteams?.groupPolicy,
314
314
  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."] : []
315
315
  });
316
- const loadMSTeamsChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-fqvE_yLN.js"), "msTeamsChannelRuntime");
316
+ const loadMSTeamsChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-CkJ9YLb5.js"), "msTeamsChannelRuntime");
317
317
  const resolveMSTeamsChannelConfig = (cfg) => ({
318
318
  allowFrom: cfg.channels?.msteams?.allowFrom,
319
319
  defaultTo: cfg.channels?.msteams?.defaultTo
@@ -580,7 +580,7 @@ const msteamsPlugin = createChatChannelPlugin({
580
580
  doctor: {
581
581
  dmAllowFromMode: "topOnly",
582
582
  groupModel: "hybrid",
583
- groupAllowFromFallbackToAllowFrom: false,
583
+ groupAllowFromFallbackToAllowFrom: true,
584
584
  warnOnEmptyGroupSenderAllowlist: true,
585
585
  collectMutableAllowlistWarnings: collectMSTeamsMutableAllowlistWarnings
586
586
  },
@@ -1095,7 +1095,7 @@ const msteamsPlugin = createChatChannelPlugin({
1095
1095
  })
1096
1096
  }),
1097
1097
  gateway: { startAccount: async (ctx) => {
1098
- const { monitorMSTeamsProvider } = await import("./src-CYZq-lQ4.js");
1098
+ const { monitorMSTeamsProvider } = await import("./src-Budn-V0e.js");
1099
1099
  const port = ctx.cfg.channels?.msteams?.webhook?.port ?? 3978;
1100
1100
  ctx.setStatus({
1101
1101
  accountId: ctx.accountId,
@@ -1,2 +1,2 @@
1
- import { t as msteamsPlugin } from "./channel-C5CVTygn.js";
1
+ import { t as msteamsPlugin } from "./channel-CQpy2Rqt.js";
2
2
  export { msteamsPlugin };
@@ -1,6 +1,6 @@
1
1
  import { s as chunkTextForOutbound } from "./runtime-api-C3EIaIpt.js";
2
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-ChPPxUzD.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-I2DM0U-s.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-btgicl3B.js";
4
4
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
6
6
  import { resolveOutboundSendDep } from "openclaw/plugin-sdk/outbound-send-deps";
@@ -1,6 +1,6 @@
1
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
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-ChPPxUzD.js";
3
- import { i as resolveMSTeamsRouteConfig, r as resolveMSTeamsReplyPolicy } from "./channel-C5CVTygn.js";
3
+ import { i as resolveMSTeamsRouteConfig, r as resolveMSTeamsReplyPolicy } from "./channel-CQpy2Rqt.js";
4
4
  import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-message";
5
5
  import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
6
  import { withFileLock } from "openclaw/plugin-sdk/file-lock";
@@ -1,5 +1,5 @@
1
1
  import { h as resolveMSTeamsCredentials } from "./graph-users-ChPPxUzD.js";
2
- import { i as msteamsSetupAdapter, t as msteamsSetupWizard } from "./setup-surface-CQrMX-nJ.js";
2
+ import { i as msteamsSetupAdapter, t as msteamsSetupWizard } from "./setup-surface-CVdYNhQt.js";
3
3
  import { t as MSTeamsChannelConfigSchema } from "./config-schema-DwOEthCC.js";
4
4
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
5
5
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
@@ -1,7 +1,7 @@
1
1
  import { O as formatUnknownError, c as normalizeQuery, f as resolveGraphToken, g as saveDelegatedTokens, h as resolveMSTeamsCredentials, o as listChannelsForTeam, p as hasConfiguredMSTeamsCredentials, s as listTeamsByName, t as searchGraphUsers, v as normalizeSecretInputString } from "./graph-users-ChPPxUzD.js";
2
2
  import { mapAllowlistResolutionInputs } from "openclaw/plugin-sdk/allow-from";
3
3
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
- import { DEFAULT_ACCOUNT_ID, createStandardChannelSetupStatus, createTopLevelChannelAllowFromSetter, createTopLevelChannelDmPolicy, createTopLevelChannelGroupPolicySetter, mergeAllowFromEntries, splitSetupEntries } from "openclaw/plugin-sdk/setup";
4
+ import { DEFAULT_ACCOUNT_ID, createSetupTranslator, createStandardChannelSetupStatus, createTopLevelChannelAllowFromSetter, createTopLevelChannelDmPolicy, createTopLevelChannelGroupPolicySetter, mergeAllowFromEntries, splitSetupEntries } from "openclaw/plugin-sdk/setup";
5
5
  import { formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
6
6
  //#region extensions/msteams/src/resolve-allowlist.ts
7
7
  function stripProviderPrefix(raw) {
@@ -219,6 +219,7 @@ async function resolveMSTeamsUserAllowlist(params) {
219
219
  }
220
220
  //#endregion
221
221
  //#region extensions/msteams/src/setup-core.ts
222
+ const t$1 = createSetupTranslator();
222
223
  const msteamsSetupAdapter = {
223
224
  resolveAccountId: () => DEFAULT_ACCOUNT_ID,
224
225
  applyAccountConfig: ({ cfg }) => ({
@@ -236,27 +237,27 @@ const channel$1 = "msteams";
236
237
  async function promptMSTeamsCredentials(prompter) {
237
238
  return {
238
239
  appId: (await prompter.text({
239
- message: "Enter MS Teams App ID",
240
- validate: (value) => value?.trim() ? void 0 : "Required"
240
+ message: t$1("wizard.msteams.appIdPrompt"),
241
+ validate: (value) => value?.trim() ? void 0 : t$1("common.required")
241
242
  })).trim(),
242
243
  appPassword: (await prompter.text({
243
- message: "Enter MS Teams App Password",
244
- validate: (value) => value?.trim() ? void 0 : "Required"
244
+ message: t$1("wizard.msteams.appPasswordPrompt"),
245
+ validate: (value) => value?.trim() ? void 0 : t$1("common.required")
245
246
  })).trim(),
246
247
  tenantId: (await prompter.text({
247
- message: "Enter MS Teams Tenant ID",
248
- validate: (value) => value?.trim() ? void 0 : "Required"
248
+ message: t$1("wizard.msteams.tenantIdPrompt"),
249
+ validate: (value) => value?.trim() ? void 0 : t$1("common.required")
249
250
  })).trim()
250
251
  };
251
252
  }
252
253
  async function noteMSTeamsCredentialHelp(prompter) {
253
254
  await prompter.note([
254
- "1) Azure Bot registration -> get App ID + Tenant ID",
255
- "2) Add a client secret (App Password)",
256
- "3) Set webhook URL + messaging endpoint",
257
- "Tip: you can also set MSTEAMS_APP_ID / MSTEAMS_APP_PASSWORD / MSTEAMS_TENANT_ID.",
258
- `Docs: ${formatDocsLink("/channels/msteams", "msteams")}`
259
- ].join("\n"), "MS Teams credentials");
255
+ t$1("wizard.msteams.helpAzureBot"),
256
+ t$1("wizard.msteams.helpClientSecret"),
257
+ t$1("wizard.msteams.helpWebhook"),
258
+ t$1("wizard.msteams.helpEnvTip"),
259
+ t$1("wizard.channels.docs", { link: formatDocsLink("/channels/msteams", "msteams") })
260
+ ].join("\n"), t$1("wizard.msteams.credentialsTitle"));
260
261
  }
261
262
  function createMSTeamsSetupWizardBase() {
262
263
  return {
@@ -265,10 +266,10 @@ function createMSTeamsSetupWizardBase() {
265
266
  resolveShouldPromptAccountIds: () => false,
266
267
  status: createStandardChannelSetupStatus({
267
268
  channelLabel: "MS Teams",
268
- configuredLabel: "configured",
269
- unconfiguredLabel: "needs app credentials",
270
- configuredHint: "configured",
271
- unconfiguredHint: "needs app creds",
269
+ configuredLabel: t$1("wizard.channels.statusConfigured"),
270
+ unconfiguredLabel: t$1("wizard.channels.statusNeedsAppCredentials"),
271
+ configuredHint: t$1("wizard.channels.statusConfigured"),
272
+ unconfiguredHint: t$1("wizard.channels.statusNeedsAppCreds"),
272
273
  configuredScore: 2,
273
274
  unconfiguredScore: 0,
274
275
  includeStatusLine: true,
@@ -285,7 +286,7 @@ function createMSTeamsSetupWizardBase() {
285
286
  let tenantId = null;
286
287
  if (!resolved && !hasConfigCreds) await noteMSTeamsCredentialHelp(prompter);
287
288
  if (canUseEnv) if (await prompter.confirm({
288
- message: "MSTEAMS_APP_ID + MSTEAMS_APP_PASSWORD + MSTEAMS_TENANT_ID detected. Use env vars?",
289
+ message: t$1("wizard.msteams.envPrompt"),
289
290
  initialValue: true
290
291
  })) next = msteamsSetupAdapter.applyAccountConfig({
291
292
  cfg: next,
@@ -295,7 +296,7 @@ function createMSTeamsSetupWizardBase() {
295
296
  else ({appId, appPassword, tenantId} = await promptMSTeamsCredentials(prompter));
296
297
  else if (hasConfigCreds) {
297
298
  if (!await prompter.confirm({
298
- message: "MS Teams credentials already configured. Keep them?",
299
+ message: t$1("wizard.msteams.credentialsKeep"),
299
300
  initialValue: true
300
301
  })) ({appId, appPassword, tenantId} = await promptMSTeamsCredentials(prompter));
301
302
  } else ({appId, appPassword, tenantId} = await promptMSTeamsCredentials(prompter));
@@ -321,6 +322,7 @@ function createMSTeamsSetupWizardBase() {
321
322
  }
322
323
  //#endregion
323
324
  //#region extensions/msteams/src/setup-surface.ts
325
+ const t = createSetupTranslator();
324
326
  const channel = "msteams";
325
327
  const setMSTeamsAllowFrom = createTopLevelChannelAllowFromSetter({ channel });
326
328
  const setMSTeamsGroupPolicy = createTopLevelChannelGroupPolicySetter({
@@ -336,22 +338,22 @@ function looksLikeGuid(value) {
336
338
  async function promptMSTeamsAllowFrom(params) {
337
339
  const existing = params.cfg.channels?.msteams?.allowFrom ?? [];
338
340
  await params.prompter.note([
339
- "Allowlist MS Teams DMs by display name, UPN/email, or user id.",
340
- "We resolve names to user IDs via Microsoft Graph when credentials allow.",
341
- "Examples:",
341
+ t("wizard.msteams.allowlistIntro"),
342
+ t("wizard.msteams.allowlistResolve"),
343
+ t("wizard.msteams.examples"),
342
344
  "- alex@example.com",
343
345
  "- Alex Johnson",
344
346
  "- 00000000-0000-0000-0000-000000000000"
345
- ].join("\n"), "MS Teams allowlist");
347
+ ].join("\n"), t("wizard.msteams.allowlistTitle"));
346
348
  while (true) {
347
349
  const parts = splitSetupEntries(await params.prompter.text({
348
- message: "MS Teams allowFrom (usernames or ids)",
350
+ message: t("wizard.msteams.allowFromPrompt"),
349
351
  placeholder: "alex@example.com, Alex Johnson",
350
352
  initialValue: existing[0] ? existing[0] : void 0,
351
- validate: (value) => value.trim() ? void 0 : "Required"
353
+ validate: (value) => value.trim() ? void 0 : t("common.required")
352
354
  }));
353
355
  if (parts.length === 0) {
354
- await params.prompter.note("Enter at least one user.", "MS Teams allowlist");
356
+ await params.prompter.note(t("wizard.msteams.enterAtLeastOneUser"), t("wizard.msteams.allowlistTitle"));
355
357
  continue;
356
358
  }
357
359
  const resolved = await resolveMSTeamsUserAllowlist({
@@ -361,7 +363,7 @@ async function promptMSTeamsAllowFrom(params) {
361
363
  if (!resolved) {
362
364
  const ids = parts.filter((part) => looksLikeGuid(part));
363
365
  if (ids.length !== parts.length) {
364
- await params.prompter.note("Graph lookup unavailable. Use user IDs only.", "MS Teams allowlist");
366
+ await params.prompter.note(t("wizard.msteams.graphLookupUnavailable"), t("wizard.msteams.allowlistTitle"));
365
367
  continue;
366
368
  }
367
369
  const unique = mergeAllowFromEntries(existing, ids);
@@ -369,7 +371,7 @@ async function promptMSTeamsAllowFrom(params) {
369
371
  }
370
372
  const unresolved = resolved.filter((item) => !item.resolved || !item.id);
371
373
  if (unresolved.length > 0) {
372
- await params.prompter.note(`Could not resolve: ${unresolved.map((item) => item.input).join(", ")}`, "MS Teams allowlist");
374
+ await params.prompter.note(t("wizard.msteams.couldNotResolve", { entries: unresolved.map((item) => item.input).join(", ") }), t("wizard.msteams.allowlistTitle"));
373
375
  continue;
374
376
  }
375
377
  const unique = mergeAllowFromEntries(existing, resolved.map((item) => item.id));
@@ -431,18 +433,18 @@ async function resolveMSTeamsGroupAllowlist(params) {
431
433
  ...unresolved.map((entry) => parseMSTeamsTeamEntry(entry)).filter(Boolean)
432
434
  ];
433
435
  const summary = [];
434
- if (resolvedChannels.length > 0) summary.push(`Resolved channels: ${resolvedChannels.map((entry) => entry.channelId).filter(Boolean).join(", ")}`);
435
- if (resolvedTeams.length > 0) summary.push(`Resolved teams: ${resolvedTeams.map((entry) => entry.teamId).filter(Boolean).join(", ")}`);
436
- if (unresolved.length > 0) summary.push(`Unresolved (kept as typed): ${unresolved.join(", ")}`);
437
- if (summary.length > 0) await params.prompter.note(summary.join("\n"), "MS Teams channels");
436
+ if (resolvedChannels.length > 0) summary.push(t("wizard.msteams.resolvedChannels", { entries: resolvedChannels.map((entry) => entry.channelId).filter(Boolean).join(", ") }));
437
+ if (resolvedTeams.length > 0) summary.push(t("wizard.msteams.resolvedTeams", { entries: resolvedTeams.map((entry) => entry.teamId).filter(Boolean).join(", ") }));
438
+ if (unresolved.length > 0) summary.push(t("wizard.msteams.unresolvedKept", { entries: unresolved.join(", ") }));
439
+ if (summary.length > 0) await params.prompter.note(summary.join("\n"), t("wizard.msteams.channelsLabel"));
438
440
  return resolvedEntries;
439
441
  } catch (err) {
440
- await params.prompter.note(`Channel lookup failed; keeping entries as typed. ${formatUnknownError(err)}`, "MS Teams channels");
442
+ await params.prompter.note(t("wizard.msteams.channelLookupFailed", { error: formatUnknownError(err) }), t("wizard.msteams.channelsLabel"));
441
443
  return resolvedEntries;
442
444
  }
443
445
  }
444
446
  const msteamsGroupAccess = {
445
- label: "MS Teams channels",
447
+ label: t("wizard.msteams.channelsLabel"),
446
448
  placeholder: "Team Name/Channel Name, teamId/conversationId",
447
449
  currentPolicy: ({ cfg }) => cfg.channels?.msteams?.groupPolicy ?? "allowlist",
448
450
  currentEntries: ({ cfg }) => listMSTeamsGroupEntries(cfg),
@@ -473,7 +475,7 @@ const msteamsSetupWizard = {
473
475
  const finalCreds = resolveMSTeamsCredentials(next.channels?.msteams);
474
476
  if (finalCreds?.type === "secret") {
475
477
  if (await params.prompter.confirm({
476
- message: "Enable delegated auth? (required for reactions and write operations)",
478
+ message: t("wizard.msteams.delegatedAuthPrompt"),
477
479
  initialValue: false
478
480
  })) {
479
481
  next = {
@@ -488,7 +490,7 @@ const msteamsSetupWizard = {
488
490
  };
489
491
  try {
490
492
  const { loginMSTeamsDelegated } = await import("./oauth-DsVj42gA.js");
491
- const progress = params.prompter.progress("MSTeams Delegated OAuth");
493
+ const progress = params.prompter.progress(t("wizard.msteams.delegatedOAuthProgress"));
492
494
  saveDelegatedTokens(await loginMSTeamsDelegated({
493
495
  isRemote: true,
494
496
  openUrl: openDelegatedOAuthUrl,
@@ -501,9 +503,9 @@ const msteamsSetupWizard = {
501
503
  clientId: finalCreds.appId,
502
504
  clientSecret: finalCreds.appPassword
503
505
  }));
504
- progress.stop("Delegated auth configured");
506
+ progress.stop(t("wizard.msteams.delegatedAuthConfigured"));
505
507
  } catch (err) {
506
- await params.prompter.note(`Delegated auth setup failed: ${formatUnknownError(err)}\nYou can retry later via the setup wizard.`, "MS Teams delegated auth");
508
+ await params.prompter.note(`Delegated auth setup failed: ${formatUnknownError(err)}\n` + t("wizard.msteams.delegatedAuthRetry"), t("wizard.msteams.delegatedAuthTitle"));
507
509
  }
508
510
  }
509
511
  }
@@ -1,8 +1,8 @@
1
1
  import { A as summarizeMapping, D as resolveDefaultGroupPolicy, E as resolveChannelMediaMaxBytes, M as getMSTeamsRuntime, N as getOptionalMSTeamsRuntime, _ as isDangerousNameMatchingEnabled, a as buildMediaPayload, b as logTypingFailure, c as createChannelMessageReplyPipeline, f as dispatchReplyFromConfigWithSettledDispatcher$1, l as createChannelPairingController, n as DEFAULT_WEBHOOK_MAX_BODY_BYTES, t as DEFAULT_ACCOUNT_ID, v as keepHttpServerTaskAlive, x as mergeAllowlist } from "./runtime-api-C3EIaIpt.js";
2
2
  import { A as ATTACHMENT_TAG_RE, B as isLikelyImageAttachment, C as loadMSTeamsSdkWithAuth, D as formatMSTeamsSendErrorHint, E as classifyMSTeamsSendError, F as estimateBase64DecodedBytes, G as resolveAttachmentFetchPolicy, H as isUrlAllowed, I as extractHtmlFromAttachment, J as safeFetchWithPolicy, K as resolveMediaSsrfPolicy, L as extractInlineImageCandidates, M as IMG_SRC_RE, N as applyAuthorizationHeaderForUrl, O as formatUnknownError, P as encodeGraphShareId, R as inferPlaceholder, S as createMSTeamsTokenProvider, T as ensureUserAgentHeader, U as normalizeContentType, V as isRecord$1, W as readNestedString, X as tryBuildGraphSharesUrlForSharedLink, Y as safeHostForUrl, _ as resolveMSTeamsStorePath, a as fetchGraphJson, b as createBotFrameworkJwtValidator, h as resolveMSTeamsCredentials, j as GRAPH_ROOT, q as resolveRequestUrl, w as buildUserAgent, x as createMSTeamsAdapter, z as isDownloadableAttachment } from "./graph-users-ChPPxUzD.js";
3
- import { d as resolveMSTeamsUserAllowlist, u as resolveMSTeamsChannelAllowlist } from "./setup-surface-CQrMX-nJ.js";
4
- import { i as resolveMSTeamsRouteConfig, n as resolveMSTeamsAllowlistMatch, r as resolveMSTeamsReplyPolicy } from "./channel-C5CVTygn.js";
5
- import { C as readJsonFile, S as createMSTeamsConversationStoreFs, T as writeJsonFile, _ as buildFileInfoCard, b as createMSTeamsPollStoreFs, 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 AI_GENERATED_ENTITY, v as parseFileConsentInvoke, w as withFileLock, x as extractMSTeamsPollVote, y as uploadToConsentUrl } from "./probe-I2DM0U-s.js";
3
+ import { d as resolveMSTeamsUserAllowlist, u as resolveMSTeamsChannelAllowlist } from "./setup-surface-CVdYNhQt.js";
4
+ import { i as resolveMSTeamsRouteConfig, n as resolveMSTeamsAllowlistMatch, r as resolveMSTeamsReplyPolicy } from "./channel-CQpy2Rqt.js";
5
+ import { C as readJsonFile, S as createMSTeamsConversationStoreFs, T as writeJsonFile, _ as buildFileInfoCard, b as createMSTeamsPollStoreFs, 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 AI_GENERATED_ENTITY, v as parseFileConsentInvoke, w as withFileLock, x as extractMSTeamsPollVote, y as uploadToConsentUrl } from "./probe-btgicl3B.js";
6
6
  import { formatAllowlistMatchMeta } from "openclaw/plugin-sdk/allow-from";
7
7
  import { createLiveMessageState, createPreviewMessageReceipt, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, markLiveMessageFinalized } from "openclaw/plugin-sdk/channel-message";
8
8
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -18,7 +18,7 @@ import fs from "node:fs/promises";
18
18
  import { channelIngressRoutes, resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
19
19
  import { logInboundDrop, resolveInboundMentionDecision, resolveInboundSessionEnvelopeContext } from "openclaw/plugin-sdk/channel-inbound";
20
20
  import { filterSupplementalContextItems, resolveChannelContextVisibilityMode, shouldIncludeSupplementalContext } from "openclaw/plugin-sdk/context-visibility-runtime";
21
- import { DEFAULT_GROUP_HISTORY_LIMIT, buildPendingHistoryContextFromMap, recordPendingHistoryEntryIfEnabled } from "openclaw/plugin-sdk/reply-history";
21
+ import { DEFAULT_GROUP_HISTORY_LIMIT, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
22
22
  import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelProgressDraftGate, formatChannelProgressDraftText, isChannelProgressDraftWorkToolName, mergeChannelProgressDraftLine, normalizeChannelProgressDraftLineIdentity, resolveChannelPreviewStreamMode, resolveChannelProgressDraftMaxLines, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewToolProgress } from "openclaw/plugin-sdk/channel-streaming";
23
23
  //#region extensions/msteams/src/feedback-reflection-prompt.ts
24
24
  /** Max chars of the thumbed-down response to include in the reflection prompt. */
@@ -2792,8 +2792,7 @@ function createMSTeamsMessageHandler(deps) {
2792
2792
  requireMention,
2793
2793
  mentioned
2794
2794
  });
2795
- recordPendingHistoryEntryIfEnabled({
2796
- historyMap: conversationHistories,
2795
+ createChannelHistoryWindow({ historyMap: conversationHistories }).record({
2797
2796
  historyKey: conversationId,
2798
2797
  limit: historyLimit,
2799
2798
  entry: {
@@ -2911,8 +2910,7 @@ function createMSTeamsMessageHandler(deps) {
2911
2910
  });
2912
2911
  const isRoomish = !isDirectMessage;
2913
2912
  const historyKey = isRoomish ? conversationId : void 0;
2914
- if (isRoomish && historyKey) combinedBody = buildPendingHistoryContextFromMap({
2915
- historyMap: conversationHistories,
2913
+ if (isRoomish && historyKey) combinedBody = createChannelHistoryWindow({ historyMap: conversationHistories }).buildPendingContext({
2916
2914
  historyKey,
2917
2915
  limit: historyLimit,
2918
2916
  currentMessage: combinedBody,
@@ -2924,11 +2922,10 @@ function createMSTeamsMessageHandler(deps) {
2924
2922
  envelope: envelopeOptions
2925
2923
  })
2926
2924
  });
2927
- const inboundHistory = isRoomish && historyKey && historyLimit > 0 ? (conversationHistories.get(historyKey) ?? []).map((entry) => ({
2928
- sender: entry.sender,
2929
- body: entry.body,
2930
- timestamp: entry.timestamp
2931
- })) : void 0;
2925
+ const inboundHistory = isRoomish && historyKey && historyLimit > 0 ? createChannelHistoryWindow({ historyMap: conversationHistories }).buildInboundHistory({
2926
+ historyKey,
2927
+ limit: historyLimit
2928
+ }) : void 0;
2932
2929
  const commandBody = text.trim();
2933
2930
  const quoteSenderAllowed = quoteInfo && quoteInfo.sender ? !isChannel || groupPolicy !== "allowlist" ? true : resolveMSTeamsAllowlistMatch({
2934
2931
  allowFrom: effectiveGroupAllowFrom,
package/dist/test-api.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as msteamsPlugin } from "./channel-C5CVTygn.js";
1
+ import { t as msteamsPlugin } from "./channel-CQpy2Rqt.js";
2
2
  export { msteamsPlugin };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/msteams",
3
- "version": "2026.5.14-beta.2",
3
+ "version": "2026.5.16-beta.1",
4
4
  "description": "OpenClaw Microsoft Teams channel plugin",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,7 +22,7 @@
22
22
  "openclaw": "workspace:*"
23
23
  },
24
24
  "peerDependencies": {
25
- "openclaw": ">=2026.5.14-beta.2"
25
+ "openclaw": ">=2026.5.16-beta.1"
26
26
  },
27
27
  "peerDependenciesMeta": {
28
28
  "openclaw": {
@@ -48,7 +48,7 @@
48
48
  "doctorCapabilities": {
49
49
  "dmAllowFromMode": "topOnly",
50
50
  "groupModel": "hybrid",
51
- "groupAllowFromFallbackToAllowFrom": false,
51
+ "groupAllowFromFallbackToAllowFrom": true,
52
52
  "warnOnEmptyGroupSenderAllowlist": true
53
53
  }
54
54
  },
@@ -58,10 +58,10 @@
58
58
  "minHostVersion": ">=2026.4.10"
59
59
  },
60
60
  "compat": {
61
- "pluginApi": ">=2026.5.14-beta.2"
61
+ "pluginApi": ">=2026.5.16-beta.1"
62
62
  },
63
63
  "build": {
64
- "openclawVersion": "2026.5.14-beta.2"
64
+ "openclawVersion": "2026.5.16-beta.1"
65
65
  },
66
66
  "release": {
67
67
  "publishToClawHub": true,