@openclaw/msteams 2026.9.1 → 2026.9.3

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.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_channel = require("./channel-CqRcu6kk.cjs");
3
- const require_channel_setup = require("./channel.setup-D2YO3F4O.cjs");
2
+ const require_channel = require("./channel-Cdm6-HsU.cjs");
3
+ const require_channel_setup = require("./channel.setup-ChwkwdLk.cjs");
4
4
  exports.createMSTeamsSetupWizardBase = require_channel_setup.createMSTeamsSetupWizardBase;
5
5
  exports.msteamsPlugin = require_channel.msteamsPlugin;
6
6
  exports.msteamsSetupAdapter = require_channel_setup.msteamsSetupAdapter;
@@ -1,15 +1,7 @@
1
- const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
2
1
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
3
- let node_crypto = require("node:crypto");
4
- node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
5
- let openclaw_plugin_sdk_collection_runtime = require("openclaw/plugin-sdk/collection-runtime");
2
+ let openclaw_plugin_sdk_approval_runtime = require("openclaw/plugin-sdk/approval-runtime");
6
3
  //#region extensions/msteams/src/approval-card-actions.ts
7
- const approvalCardBindings = /* @__PURE__ */ new Map();
8
- const approvalCardResolvingTokens = /* @__PURE__ */ new Set();
9
- const MSTEAMS_APPROVAL_CARD_BINDING_MAX_ENTRIES = 1024;
10
- function createMSTeamsApprovalToken() {
11
- return node_crypto.default.randomBytes(18).toString("base64url");
12
- }
4
+ const msTeamsApprovalControls = (0, openclaw_plugin_sdk_approval_runtime.createNativeApprovalControlRegistry)({ releaseClaimOnLookupExpiry: true });
13
5
  function readMSTeamsApprovalActionToken(value) {
14
6
  if (!(0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(value)) return null;
15
7
  const action = (0, openclaw_plugin_sdk_string_coerce_runtime.isRecord)(value.action) ? value.action : void 0;
@@ -17,43 +9,6 @@ function readMSTeamsApprovalActionToken(value) {
17
9
  if (submitted.openclawAction !== "approval") return null;
18
10
  return (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(submitted.token) ?? null;
19
11
  }
20
- function registerMSTeamsApprovalCardBinding(binding) {
21
- if (binding.expiresAtMs <= Date.now()) return false;
22
- approvalCardBindings.delete(binding.token);
23
- approvalCardBindings.set(binding.token, binding);
24
- (0, openclaw_plugin_sdk_collection_runtime.pruneMapToMaxSize)(approvalCardBindings, MSTEAMS_APPROVAL_CARD_BINDING_MAX_ENTRIES);
25
- return true;
26
- }
27
- function getMSTeamsApprovalCardBinding(token) {
28
- const binding = approvalCardBindings.get(token);
29
- if (!binding) return null;
30
- if (binding.expiresAtMs <= Date.now()) {
31
- approvalCardBindings.delete(token);
32
- approvalCardResolvingTokens.delete(token);
33
- return null;
34
- }
35
- return binding;
36
- }
37
- function claimMSTeamsApprovalCardBinding(token) {
38
- const binding = getMSTeamsApprovalCardBinding(token);
39
- if (!binding) return { kind: "missing" };
40
- if (approvalCardResolvingTokens.has(token)) return { kind: "in-flight" };
41
- approvalCardResolvingTokens.add(token);
42
- return {
43
- kind: "claimed",
44
- binding
45
- };
46
- }
47
- function completeMSTeamsApprovalCardBinding(token) {
48
- approvalCardResolvingTokens.delete(token);
49
- approvalCardBindings.delete(token);
50
- }
51
- function releaseMSTeamsApprovalCardBinding(token) {
52
- approvalCardResolvingTokens.delete(token);
53
- }
54
- function unregisterMSTeamsApprovalCardBindings(tokens) {
55
- for (const token of tokens) completeMSTeamsApprovalCardBinding(token);
56
- }
57
12
  //#endregion
58
13
  //#region extensions/msteams/src/approval-card.ts
59
14
  function buildCardHeading(title, subtitle) {
@@ -146,15 +101,12 @@ function buildAdaptiveCard(body, actions) {
146
101
  ...actions?.length ? { actions } : {}
147
102
  };
148
103
  }
149
- function formatApprovalDecision(decision) {
150
- return decision === "allow-once" ? "Allowed once" : decision === "allow-always" ? "Allowed always" : "Denied";
151
- }
152
104
  function buildMSTeamsPendingApprovalCard(params) {
153
105
  const { view, nowMs } = params;
154
106
  const kindLabel = view.approvalKind === "plugin" ? "Plugin" : view.approvalKind === "system-agent" ? "OpenClaw Change" : "Exec";
155
107
  const actionTokens = [];
156
108
  const actions = view.actions.map(({ decision, label }) => {
157
- const token = createMSTeamsApprovalToken();
109
+ const token = msTeamsApprovalControls.createToken();
158
110
  actionTokens.push({
159
111
  token,
160
112
  decision
@@ -187,7 +139,7 @@ function buildMSTeamsResolvedApprovalCard(view) {
187
139
  const kindLabel = view.approvalKind === "plugin" ? "Plugin" : view.approvalKind === "system-agent" ? "OpenClaw Change" : "Exec";
188
140
  const resolvedBy = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalString)(view.resolvedBy);
189
141
  return buildAdaptiveCard([
190
- ...buildCardHeading(`${kindLabel} Approval: ${view.approvalKind === "system-agent" && view.terminalStatus === "cancelled" ? "Cancelled" : view.approvalKind === "system-agent" && view.applicationStatus === "applied" ? "Applied" : view.approvalKind === "system-agent" && view.applicationStatus === "not-applied" ? "Not applied" : formatApprovalDecision(view.decision)}`, resolvedBy ? `Resolved by ${resolvedBy}` : "Resolved"),
142
+ ...buildCardHeading(`${kindLabel} Approval: ${(0, openclaw_plugin_sdk_approval_runtime.formatChannelApprovalResolvedLabel)(view)}`, resolvedBy ? `Resolved by ${resolvedBy}` : "Resolved"),
191
143
  ...buildApprovalSubject(view),
192
144
  buildApprovalMetadata(view.approvalId, view.metadata)
193
145
  ]);
@@ -203,7 +155,7 @@ function buildMSTeamsCanonicalApprovalTerminalCard(result) {
203
155
  const { approval } = result;
204
156
  const { presentation } = approval;
205
157
  const kindLabel = presentation.kind === "exec" ? "Exec" : presentation.kind === "plugin" ? "Plugin" : "System Agent";
206
- const outcome = approval.status === "allowed" ? formatApprovalDecision(approval.decision) : approval.status === "denied" ? "Denied" : approval.status === "expired" ? "Expired" : "Cancelled";
158
+ const outcome = approval.status === "allowed" ? (0, openclaw_plugin_sdk_approval_runtime.formatApprovalDecisionLabel)(approval.decision) : approval.status === "denied" ? "Denied" : approval.status === "expired" ? "Expired" : "Cancelled";
207
159
  const subject = presentation.kind === "exec" ? [{
208
160
  type: "TextBlock",
209
161
  text: "Command",
@@ -269,22 +221,10 @@ Object.defineProperty(exports, "buildMSTeamsResolvedApprovalCard", {
269
221
  return buildMSTeamsResolvedApprovalCard;
270
222
  }
271
223
  });
272
- Object.defineProperty(exports, "claimMSTeamsApprovalCardBinding", {
273
- enumerable: true,
274
- get: function() {
275
- return claimMSTeamsApprovalCardBinding;
276
- }
277
- });
278
- Object.defineProperty(exports, "completeMSTeamsApprovalCardBinding", {
224
+ Object.defineProperty(exports, "msTeamsApprovalControls", {
279
225
  enumerable: true,
280
226
  get: function() {
281
- return completeMSTeamsApprovalCardBinding;
282
- }
283
- });
284
- Object.defineProperty(exports, "getMSTeamsApprovalCardBinding", {
285
- enumerable: true,
286
- get: function() {
287
- return getMSTeamsApprovalCardBinding;
227
+ return msTeamsApprovalControls;
288
228
  }
289
229
  });
290
230
  Object.defineProperty(exports, "readMSTeamsApprovalActionToken", {
@@ -293,21 +233,3 @@ Object.defineProperty(exports, "readMSTeamsApprovalActionToken", {
293
233
  return readMSTeamsApprovalActionToken;
294
234
  }
295
235
  });
296
- Object.defineProperty(exports, "registerMSTeamsApprovalCardBinding", {
297
- enumerable: true,
298
- get: function() {
299
- return registerMSTeamsApprovalCardBinding;
300
- }
301
- });
302
- Object.defineProperty(exports, "releaseMSTeamsApprovalCardBinding", {
303
- enumerable: true,
304
- get: function() {
305
- return releaseMSTeamsApprovalCardBinding;
306
- }
307
- });
308
- Object.defineProperty(exports, "unregisterMSTeamsApprovalCardBindings", {
309
- enumerable: true,
310
- get: function() {
311
- return unregisterMSTeamsApprovalCardBindings;
312
- }
313
- });
@@ -1,7 +1,7 @@
1
1
  const require_resolve_allowlist = require("./resolve-allowlist-CoKmLXYe.cjs");
2
- const require_channel = require("./channel-CqRcu6kk.cjs");
3
- const require_approval_card = require("./approval-card-ClrTjCsL.cjs");
4
- const require_send = require("./send-CAKTR80N.cjs");
2
+ const require_channel = require("./channel-Cdm6-HsU.cjs");
3
+ const require_approval_card = require("./approval-card-CPNH_q3P.cjs");
4
+ const require_send = require("./send-Bw4W8RO7.cjs");
5
5
  let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
6
6
  let openclaw_plugin_sdk_approval_native_runtime = require("openclaw/plugin-sdk/approval-native-runtime");
7
7
  let openclaw_plugin_sdk_approval_handler_runtime = require("openclaw/plugin-sdk/approval-handler-runtime");
@@ -79,7 +79,7 @@ const msTeamsApprovalNativeRuntime = (0, openclaw_plugin_sdk_approval_handler_ru
79
79
  interactions: {
80
80
  bindPending: ({ entry, request, approvalKind, view, pendingPayload }) => {
81
81
  const tokens = [];
82
- for (const actionToken of entry.actionTokens) if (require_approval_card.registerMSTeamsApprovalCardBinding({
82
+ for (const actionToken of entry.actionTokens) if (require_approval_card.msTeamsApprovalControls.register({
83
83
  token: actionToken.token,
84
84
  accountId: entry.accountId,
85
85
  approvalId: request.id,
@@ -92,8 +92,8 @@ const msTeamsApprovalNativeRuntime = (0, openclaw_plugin_sdk_approval_handler_ru
92
92
  })) tokens.push(actionToken.token);
93
93
  return tokens.length > 0 ? tokens : null;
94
94
  },
95
- unbindPending: ({ binding }) => require_approval_card.unregisterMSTeamsApprovalCardBindings(binding),
96
- cancelDelivered: ({ entry }) => require_approval_card.unregisterMSTeamsApprovalCardBindings(entry.actionTokens.map(({ token }) => token))
95
+ unbindPending: ({ binding }) => require_approval_card.msTeamsApprovalControls.unregister(binding),
96
+ cancelDelivered: ({ entry }) => require_approval_card.msTeamsApprovalControls.unregister(entry.actionTokens.map(({ token }) => token))
97
97
  },
98
98
  observe: { onDeliveryError: ({ cfg, error, plannedTarget, request, approvalKind, pendingPayload }) => {
99
99
  log.error(`msteams approvals: failed to deliver request ${request.id}: ${String(error)}`);
@@ -2,7 +2,7 @@ require("./runtime-api.cjs");
2
2
  const require_resolve_allowlist = require("./resolve-allowlist-CoKmLXYe.cjs");
3
3
  const require_directory_contract_api = require("./directory-contract-api.cjs");
4
4
  const require_thread_session = require("./thread-session-p8FNgohv.cjs");
5
- const require_channel_setup = require("./channel.setup-D2YO3F4O.cjs");
5
+ const require_channel_setup = require("./channel.setup-ChwkwdLk.cjs");
6
6
  let openclaw_plugin_sdk_approval_handler_adapter_runtime = require("openclaw/plugin-sdk/approval-handler-adapter-runtime");
7
7
  let openclaw_plugin_sdk_channel_core = require("openclaw/plugin-sdk/channel-core");
8
8
  let openclaw_plugin_sdk_channel_outbound = require("openclaw/plugin-sdk/channel-outbound");
@@ -330,7 +330,7 @@ const msTeamsLazyApprovalNativeRuntime = (0, openclaw_plugin_sdk_approval_handle
330
330
  request
331
331
  }),
332
332
  load: async () => {
333
- const { msTeamsApprovalNativeRuntime } = await Promise.resolve().then(() => require("./approval-handler.runtime-9rMFhyLp.cjs"));
333
+ const { msTeamsApprovalNativeRuntime } = await Promise.resolve().then(() => require("./approval-handler.runtime-CoTQG4FS.cjs"));
334
334
  return msTeamsApprovalNativeRuntime;
335
335
  }
336
336
  });
@@ -781,7 +781,7 @@ const collectMSTeamsSecurityFindings = openclaw_plugin_sdk_channel_policy.create
781
781
  severity: "critical",
782
782
  title: "MS Teams security warning"
783
783
  });
784
- const loadMSTeamsChannelRuntime = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeNamedExport)(() => Promise.resolve().then(() => require("./channel.runtime-BAy59d1L.cjs")), "msTeamsChannelRuntime");
784
+ const loadMSTeamsChannelRuntime = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeNamedExport)(() => Promise.resolve().then(() => require("./channel.runtime-__5ZQlfG.cjs")), "msTeamsChannelRuntime");
785
785
  function jsonActionResult(data) {
786
786
  return {
787
787
  content: [{
@@ -1524,7 +1524,7 @@ const msteamsPlugin = (0, openclaw_plugin_sdk_channel_core.createChatChannelPlug
1524
1524
  })
1525
1525
  }),
1526
1526
  gateway: { startAccount: async (ctx) => {
1527
- const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./src-CyNCea9B.cjs"));
1527
+ const { monitorMSTeamsProvider } = await Promise.resolve().then(() => require("./src-B--Qc6lj.cjs"));
1528
1528
  const port = ctx.cfg.channels?.msteams?.webhook?.port ?? 3978;
1529
1529
  const statusSink = (0, openclaw_plugin_sdk_channel_outbound.createAccountStatusSink)({
1530
1530
  accountId: ctx.accountId,
@@ -1,3 +1,3 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_config_schema = require("./config-schema-MyN2lamA.cjs");
2
+ const require_config_schema = require("./config-schema-D22Lr1Qk.cjs");
3
3
  exports.MSTeamsChannelConfigSchema = require_config_schema.MSTeamsChannelConfigSchema;
@@ -1,3 +1,3 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_channel = require("./channel-CqRcu6kk.cjs");
2
+ const require_channel = require("./channel-Cdm6-HsU.cjs");
3
3
  exports.msteamsPlugin = require_channel.msteamsPlugin;
@@ -1,10 +1,10 @@
1
1
  require("./runtime-api.cjs");
2
2
  const require_resolve_allowlist = require("./resolve-allowlist-CoKmLXYe.cjs");
3
- const require_channel = require("./channel-CqRcu6kk.cjs");
4
- const require_channel_setup = require("./channel.setup-D2YO3F4O.cjs");
5
- const require_polls = require("./polls-P86qBpeV.cjs");
6
- const require_send = require("./send-CAKTR80N.cjs");
7
- const require_reaction_types = require("./reaction-types-DcJBoyFP.cjs");
3
+ const require_channel = require("./channel-Cdm6-HsU.cjs");
4
+ const require_channel_setup = require("./channel.setup-ChwkwdLk.cjs");
5
+ const require_polls = require("./polls-BBdZPx_R.cjs");
6
+ const require_send = require("./send-Bw4W8RO7.cjs");
7
+ const require_reaction_types = require("./reaction-types-zP91Ncwk.cjs");
8
8
  let openclaw_plugin_sdk_channel_outbound = require("openclaw/plugin-sdk/channel-outbound");
9
9
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
10
10
  let openclaw_plugin_sdk_reply_payload = require("openclaw/plugin-sdk/reply-payload");
@@ -1,6 +1,6 @@
1
1
  const require_resolve_allowlist = require("./resolve-allowlist-CoKmLXYe.cjs");
2
2
  require("./secret-input-C65t6kjM.cjs");
3
- const require_config_schema = require("./config-schema-MyN2lamA.cjs");
3
+ const require_config_schema = require("./config-schema-D22Lr1Qk.cjs");
4
4
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
5
5
  let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
6
6
  let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
@@ -556,7 +556,10 @@ const msteamsSetupPlugin = {
556
556
  media: true,
557
557
  reactions: true
558
558
  },
559
- reload: { configPrefixes: ["channels.msteams"] },
559
+ reload: {
560
+ configPrefixes: ["channels.msteams"],
561
+ noopPrefixes: ["messages.inbound"]
562
+ },
560
563
  configSchema: require_config_schema.MSTeamsChannelConfigSchema,
561
564
  config: {
562
565
  ...msteamsConfigAdapter,
@@ -138,19 +138,10 @@ const MSTeamsConfigSchema = zod.z.object({
138
138
  connectionName: zod.z.string().optional()
139
139
  }).strict().optional()
140
140
  }).strict().superRefine((value, ctx) => {
141
- (0, openclaw_plugin_sdk_channel_config_schema.requireOpenAllowFrom)({
142
- policy: value.dmPolicy,
143
- allowFrom: value.allowFrom,
144
- ctx,
145
- path: ["allowFrom"],
146
- message: "channels.msteams.dmPolicy=\"open\" requires channels.msteams.allowFrom to include \"*\""
147
- });
148
- (0, openclaw_plugin_sdk_channel_config_schema.requireAllowlistAllowFrom)({
149
- policy: value.dmPolicy,
150
- allowFrom: value.allowFrom,
151
- ctx,
152
- path: ["allowFrom"],
153
- message: "channels.msteams.dmPolicy=\"allowlist\" requires channels.msteams.allowFrom to contain at least one sender ID"
141
+ (0, openclaw_plugin_sdk_channel_config_schema.refineChannelDmPolicy)({
142
+ channelId: "msteams",
143
+ value,
144
+ ctx
154
145
  });
155
146
  if (value.sso?.enabled === true && !value.sso.connectionName?.trim()) ctx.addIssue({
156
147
  code: zod.z.ZodIssueCode.custom,
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
3
3
  const require_delegated_state = require("./delegated-state-DiEz9JIa.cjs");
4
- const require_polls = require("./polls-P86qBpeV.cjs");
5
- const require_sso_token_store = require("./sso-token-store-CNbRhz-A.cjs");
4
+ const require_polls = require("./polls-BBdZPx_R.cjs");
5
+ const require_sso_token_store = require("./sso-token-store-DTeYxubp.cjs");
6
6
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
7
7
  let node_crypto = require("node:crypto");
8
8
  node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
@@ -11,6 +11,7 @@ node_fs_promises = require_rolldown_runtime.__toESM(node_fs_promises, 1);
11
11
  let node_path = require("node:path");
12
12
  node_path = require_rolldown_runtime.__toESM(node_path, 1);
13
13
  let openclaw_plugin_sdk_runtime_doctor_migrations = require("openclaw/plugin-sdk/runtime-doctor-migrations");
14
+ let openclaw_plugin_sdk_session_store_paths = require("openclaw/plugin-sdk/session-store-paths");
14
15
  //#region extensions/msteams/config-doctor-api.ts
15
16
  const streamingAliasMigration = (0, openclaw_plugin_sdk_runtime_doctor_migrations.defineChannelAliasMigration)({
16
17
  channelId: "msteams",
@@ -68,10 +69,9 @@ function listAgentIds(config) {
68
69
  for (const agent of config.agents?.list ?? []) if (typeof agent.id === "string" && agent.id.trim()) ids.add(agent.id.trim());
69
70
  return [...ids];
70
71
  }
71
- async function listCandidateStorePaths(params) {
72
- const { resolveStorePath } = await import("openclaw/plugin-sdk/session-store-runtime");
72
+ function listCandidateStorePaths(params) {
73
73
  const paths = /* @__PURE__ */ new Set();
74
- for (const agentId of listAgentIds(params.config)) paths.add(resolveStorePath(params.config.session?.store, {
74
+ for (const agentId of listAgentIds(params.config)) paths.add((0, openclaw_plugin_sdk_session_store_paths.resolveStorePath)(params.config.session?.store, {
75
75
  agentId,
76
76
  env: params.env
77
77
  }));
@@ -437,14 +437,14 @@ const stateMigrations = [
437
437
  id: "msteams-feedback-learnings-json-to-plugin-state",
438
438
  label: "Microsoft Teams feedback learnings",
439
439
  async detectLegacyState(params) {
440
- const files = (await Promise.all((await listCandidateStorePaths(params)).map((storePath) => listLegacyLearningFiles(storePath)))).flat();
440
+ const files = (await Promise.all(listCandidateStorePaths(params).map((storePath) => listLegacyLearningFiles(storePath)))).flat();
441
441
  if (files.length === 0) return null;
442
442
  return { preview: [`- Microsoft Teams feedback learnings: ${files.length} ${files.length === 1 ? "file" : "files"} -> plugin state (${LEARNINGS_NAMESPACE})`] };
443
443
  },
444
444
  async migrateLegacyState(params) {
445
445
  const changes = [];
446
446
  const warnings = [];
447
- const files = (await Promise.all((await listCandidateStorePaths(params)).map((storePath) => listLegacyLearningFiles(storePath)))).flat();
447
+ const files = (await Promise.all(listCandidateStorePaths(params).map((storePath) => listLegacyLearningFiles(storePath)))).flat();
448
448
  const store = params.context.openPluginStateKeyedStore({
449
449
  namespace: LEARNINGS_NAMESPACE,
450
450
  maxEntries: MAX_LEARNING_ENTRIES
@@ -2,8 +2,8 @@ const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
2
2
  const require_runtime = require("./runtime-gZTAuFux.cjs");
3
3
  require("./runtime-api.cjs");
4
4
  const require_resolve_allowlist = require("./resolve-allowlist-CoKmLXYe.cjs");
5
- const require_channel_setup = require("./channel.setup-D2YO3F4O.cjs");
6
- const require_polls = require("./polls-P86qBpeV.cjs");
5
+ const require_channel_setup = require("./channel.setup-ChwkwdLk.cjs");
6
+ const require_polls = require("./polls-BBdZPx_R.cjs");
7
7
  let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime");
8
8
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
9
9
  let openclaw_plugin_sdk_provider_http = require("openclaw/plugin-sdk/provider-http");
@@ -18,6 +18,7 @@ node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
18
18
  let node_path = require("node:path");
19
19
  node_path = require_rolldown_runtime.__toESM(node_path, 1);
20
20
  let openclaw_plugin_sdk_runtime_env = require("openclaw/plugin-sdk/runtime-env");
21
+ let openclaw_plugin_sdk_blob_runtime = require("openclaw/plugin-sdk/blob-runtime");
21
22
  let openclaw_plugin_sdk_global_singleton = require("openclaw/plugin-sdk/global-singleton");
22
23
  let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
23
24
  let openclaw_plugin_sdk_reply_chunking = require("openclaw/plugin-sdk/reply-chunking");
@@ -153,7 +154,7 @@ async function uploadToConsentUrl(params) {
153
154
  "Content-Type": params.contentType ?? "application/octet-stream",
154
155
  "Content-Range": `bytes 0-${params.buffer.length - 1}/${params.buffer.length}`
155
156
  },
156
- body: new Uint8Array(params.buffer)
157
+ body: new Blob([(0, openclaw_plugin_sdk_blob_runtime.bufferToBlobPart)(params.buffer)])
157
158
  }, params.timeoutMs ?? require_resolve_allowlist.resolveMSTeamsSharePointUploadTimeoutMs(params.buffer.length), fetchFn);
158
159
  await res.body?.cancel().catch(() => void 0);
159
160
  if (!res.ok) throw new Error(`File upload to consent URL failed: ${res.status} ${res.statusText}`);
@@ -244,9 +245,13 @@ async function withPendingUploadLock(options, run) {
244
245
  async function readUploadRows(id, metaStore, chunkStore) {
245
246
  const meta = await metaStore.lookup(buildMetaKey(id));
246
247
  if (!meta) return;
248
+ if (!Number.isSafeInteger(meta.chunkCount) || meta.chunkCount < 1 || meta.chunkCount > MAX_CHUNKS_PER_UPLOAD) return;
249
+ const records = await chunkStore.lookupMany?.(Array.from({ length: meta.chunkCount }, (_, index) => buildChunkKey(id, index)));
247
250
  const chunks = [];
248
251
  for (let index = 0; index < meta.chunkCount; index += 1) {
249
- const chunk = await chunkStore.lookup(buildChunkKey(id, index));
252
+ const result = records?.[index];
253
+ if (result && !result.ok) throw result.error;
254
+ const chunk = records ? result?.value : await chunkStore.lookup(buildChunkKey(id, index));
250
255
  if (!chunk || chunk.id !== id || chunk.index !== index) return;
251
256
  chunks.push(Buffer.from(chunk.dataBase64, "base64"));
252
257
  }
@@ -551,25 +556,25 @@ function createTokenPrefix(text, label) {
551
556
  return prefix;
552
557
  }
553
558
  function restoreTokens(text, prefix, values) {
559
+ if (!text.includes(prefix)) return text;
554
560
  const escapedPrefix = prefix.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
555
561
  return text.replace(new RegExp(`${escapedPrefix}(\\d+)${TOKEN_END}`, "gu"), (_token, index) => values[Number(index)] ?? "");
556
562
  }
557
563
  function rewriteMarkdownIR(ir, edits) {
558
- const ordered = [...edits].toSorted((a, b) => a.start - b.start);
564
+ const ordered = edits.toSorted((a, b) => a.start - b.start);
565
+ const cumulativeDeltas = [];
566
+ const exactEdits = /* @__PURE__ */ new Map();
559
567
  let text = "";
560
568
  let cursor = 0;
569
+ let delta = 0;
561
570
  for (const edit of ordered) {
562
571
  text += ir.text.slice(cursor, edit.start) + edit.text;
563
572
  cursor = edit.end;
564
- }
565
- text += ir.text.slice(cursor);
566
- const cumulativeDeltas = [];
567
- let delta = 0;
568
- for (const edit of ordered) {
569
573
  delta += edit.text.length - (edit.end - edit.start);
570
574
  cumulativeDeltas.push(delta);
575
+ exactEdits.set(`${edit.start}:${edit.end}`, edit);
571
576
  }
572
- const exactEdits = new Map(ordered.map((edit) => [`${edit.start}:${edit.end}`, edit]));
577
+ text += ir.text.slice(cursor);
573
578
  const mapOffset = (offset) => {
574
579
  let low = 0;
575
580
  let high = ordered.length;
@@ -666,43 +671,22 @@ function scanDelimitedMarkdown(text, start, nestedOpener) {
666
671
  }
667
672
  return fallbackNext === void 0 ? void 0 : { next: fallbackNext };
668
673
  }
669
- function protectMarkdownImages(text, tokenPrefix, images) {
670
- let protectedText = "";
671
- let cursor = 0;
672
- let searchFrom = 0;
673
- while (searchFrom < text.length) {
674
- const start = text.indexOf("![", searchFrom);
675
- if (start < 0) break;
676
- const scan = scanDelimitedMarkdown(text, start, "![");
677
- if (!scan) break;
678
- if ("next" in scan) {
679
- searchFrom = scan.next;
680
- continue;
681
- }
682
- protectedText += text.slice(cursor, start);
683
- const index = images.push(text.slice(start, scan.end)) - 1;
684
- protectedText += `${tokenPrefix}i${index}${TOKEN_END}`;
685
- cursor = scan.end;
686
- searchFrom = scan.end;
687
- }
688
- return protectedText + text.slice(cursor);
689
- }
690
- function protectMSTeamsMentions(text, tokenPrefix, mentions) {
674
+ function protectDelimitedMarkdown(text, opener, tokenPrefix, values) {
691
675
  let protectedText = "";
692
676
  let cursor = 0;
693
677
  let searchFrom = 0;
694
678
  while (searchFrom < text.length) {
695
- const start = text.indexOf("@[", searchFrom);
679
+ const start = text.indexOf(opener, searchFrom);
696
680
  if (start < 0) break;
697
- const scan = scanDelimitedMarkdown(text, start, "@[");
681
+ const scan = scanDelimitedMarkdown(text, start, opener);
698
682
  if (!scan) break;
699
683
  if ("next" in scan) {
700
684
  searchFrom = scan.next;
701
685
  continue;
702
686
  }
703
687
  protectedText += text.slice(cursor, start);
704
- const index = mentions.push(text.slice(start, scan.end)) - 1;
705
- protectedText += `${tokenPrefix}m${index}${TOKEN_END}`;
688
+ const index = values.push(text.slice(start, scan.end)) - 1;
689
+ protectedText += `${tokenPrefix}${index}${TOKEN_END}`;
706
690
  cursor = scan.end;
707
691
  searchFrom = scan.end;
708
692
  }
@@ -880,6 +864,7 @@ function protectMSTeamsCode(ir, tokenPrefix, code, protectedValues) {
880
864
  };
881
865
  }
882
866
  function formatMSTeamsMarkdown(markdown, tableMode) {
867
+ if (markdown === "") return markdown;
883
868
  const rawTables = [];
884
869
  const escapedMarkdown = [];
885
870
  const codeRegions = [];
@@ -887,10 +872,10 @@ function formatMSTeamsMarkdown(markdown, tableMode) {
887
872
  const mentions = [];
888
873
  const entities = [];
889
874
  const tokenPrefix = createTokenPrefix(markdown, "msteamsformat");
890
- const mentionsProtected = protectMSTeamsMentions(protectMarkdownImages(markdown.replace(MARKDOWN_ENTITY_RE, (entity) => {
875
+ const mentionsProtected = protectDelimitedMarkdown(protectDelimitedMarkdown(markdown.replace(MARKDOWN_ENTITY_RE, (entity) => {
891
876
  const index = entities.push(entity) - 1;
892
877
  return `${tokenPrefix}h${index}${TOKEN_END}`;
893
- }), tokenPrefix, images), tokenPrefix, mentions);
878
+ }), "![", `${tokenPrefix}i`, images), "@[", `${tokenPrefix}m`, mentions);
894
879
  const tableInput = (0, openclaw_plugin_sdk_text_chunking.convertMarkdownTables)(mentionsProtected, tableMode);
895
880
  const protectedMarkdown = (tableMode === "off" ? protectRawTablesOutsideFences(tableInput, tokenPrefix, rawTables) : tableInput).replace(ESCAPED_MARKDOWN_RE, (escaped) => {
896
881
  const index = escapedMarkdown.push(escaped) - 1;
@@ -1009,7 +994,7 @@ async function uploadToSharePoint(params) {
1009
994
  Authorization: `Bearer ${token}`,
1010
995
  "Content-Type": params.contentType ?? "application/octet-stream"
1011
996
  },
1012
- body: new Uint8Array(params.buffer),
997
+ body: new Blob([(0, openclaw_plugin_sdk_blob_runtime.bufferToBlobPart)(params.buffer)]),
1013
998
  signal
1014
999
  });
1015
1000
  if (!res.ok) throw await require_resolve_allowlist.createMSTeamsHttpError(res, "SharePoint upload failed");
@@ -1225,15 +1210,6 @@ function extractMessageId(response) {
1225
1210
  return id;
1226
1211
  }
1227
1212
  //#endregion
1228
- //#region extensions/msteams/src/ai-entity.ts
1229
- /** AI-generated content entity added to every outbound AI message. */
1230
- const AI_GENERATED_ENTITY = {
1231
- type: "https://schema.org/Message",
1232
- "@type": "Message",
1233
- "@id": "",
1234
- additionalType: ["AIGeneratedContent"]
1235
- };
1236
- //#endregion
1237
1213
  //#region extensions/msteams/src/mentions.ts
1238
1214
  /**
1239
1215
  * Check whether an ID looks like a valid Teams user/bot identifier.
@@ -1282,6 +1258,24 @@ function parseMentions(text) {
1282
1258
  };
1283
1259
  }
1284
1260
  //#endregion
1261
+ //#region extensions/msteams/src/message-activity.ts
1262
+ const AI_GENERATED_ENTITY = {
1263
+ type: "https://schema.org/Message",
1264
+ "@type": "Message",
1265
+ "@context": "https://schema.org",
1266
+ "@id": "",
1267
+ additionalType: ["AIGeneratedContent"]
1268
+ };
1269
+ /** Build final transport text and its matching entities after Markdown rendering. */
1270
+ function buildMSTeamsMessageActivity(text) {
1271
+ const parsed = parseMentions(text ?? "");
1272
+ return {
1273
+ type: "message",
1274
+ ...text === void 0 ? {} : { text: parsed.text },
1275
+ entities: [...parsed.entities, AI_GENERATED_ENTITY]
1276
+ };
1277
+ }
1278
+ //#endregion
1285
1279
  //#region extensions/msteams/src/revoked-context.ts
1286
1280
  async function withRevokedProxyFallback(params) {
1287
1281
  try {
@@ -1551,13 +1545,8 @@ function renderReplyPayloadsToMessages(replies, options) {
1551
1545
  return out;
1552
1546
  }
1553
1547
  async function buildActivity(msg, conversationRef, tokenProvider, sharePointSiteId, mediaMaxBytes, options) {
1554
- const activity = { type: "message" };
1548
+ const activity = buildMSTeamsMessageActivity(msg.text);
1555
1549
  activity.channelData = { feedbackLoopEnabled: options?.feedbackLoopEnabled ?? false };
1556
- if (msg.text) {
1557
- const { text: formattedText, entities } = parseMentions(msg.text);
1558
- activity.text = formattedText;
1559
- activity.entities = [...entities.length > 0 ? entities : [], AI_GENERATED_ENTITY];
1560
- } else activity.entities = [AI_GENERATED_ENTITY];
1561
1550
  if (msg.mediaUrl) {
1562
1551
  let contentUrl = msg.mediaUrl;
1563
1552
  let contentType = await getMimeType(msg.mediaUrl);
@@ -1728,6 +1717,12 @@ Object.defineProperty(exports, "buildFileInfoCard", {
1728
1717
  return buildFileInfoCard;
1729
1718
  }
1730
1719
  });
1720
+ Object.defineProperty(exports, "buildMSTeamsMessageActivity", {
1721
+ enumerable: true,
1722
+ get: function() {
1723
+ return buildMSTeamsMessageActivity;
1724
+ }
1725
+ });
1731
1726
  Object.defineProperty(exports, "buildTeamsFileInfoCard", {
1732
1727
  enumerable: true,
1733
1728
  get: function() {
@@ -12,9 +12,6 @@ let openclaw_plugin_sdk_keyed_async_queue = require("openclaw/plugin-sdk/keyed-a
12
12
  function normalizeStoredConversationId(raw) {
13
13
  return raw.split(";")[0] ?? raw;
14
14
  }
15
- function parseStoredConversationTimestamp(value) {
16
- return (0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(value) ?? null;
17
- }
18
15
  function toConversationStoreEntries(entries) {
19
16
  return Array.from(entries, ([conversationId, reference]) => ({
20
17
  conversationId,
@@ -43,7 +40,7 @@ function findPreferredDmConversationByUserId(entries, id) {
43
40
  }
44
41
  const candidates = personalMatches.length > 0 ? personalMatches : unknownTypeMatches;
45
42
  if (candidates.length === 0) return null;
46
- if (candidates.length > 1) candidates.sort((a, b) => (parseStoredConversationTimestamp(b.reference.lastSeenAt) ?? 0) - (parseStoredConversationTimestamp(a.reference.lastSeenAt) ?? 0));
43
+ if (candidates.length > 1) candidates.sort((a, b) => ((0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(b.reference.lastSeenAt) ?? 0) - ((0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(a.reference.lastSeenAt) ?? 0));
47
44
  return candidates[0] ?? null;
48
45
  }
49
46
  //#endregion
@@ -130,12 +127,12 @@ function getStoredConversationId(reference) {
130
127
  }
131
128
  function selectRetainedMSTeamsConversations(conversations, ttlMs = MSTEAMS_CONVERSATION_TTL_MS) {
132
129
  const retained = Object.entries(conversations).filter(([, reference]) => {
133
- const lastSeenAt = parseStoredConversationTimestamp(reference.lastSeenAt);
130
+ const lastSeenAt = (0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(reference.lastSeenAt);
134
131
  return lastSeenAt == null || Date.now() - lastSeenAt <= ttlMs;
135
132
  });
136
133
  if (retained.length <= MSTEAMS_MAX_CONVERSATIONS) return retained;
137
134
  retained.sort((a, b) => {
138
- return (parseStoredConversationTimestamp(a[1].lastSeenAt) ?? 0) - (parseStoredConversationTimestamp(b[1].lastSeenAt) ?? 0) || a[0].localeCompare(b[0]);
135
+ return ((0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(a[1].lastSeenAt) ?? 0) - ((0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(b[1].lastSeenAt) ?? 0) || a[0].localeCompare(b[0]);
139
136
  });
140
137
  return retained.slice(retained.length - MSTEAMS_MAX_CONVERSATIONS);
141
138
  }
@@ -143,7 +140,7 @@ function createMSTeamsConversationStoreState(params) {
143
140
  const ttlMs = params?.ttlMs ?? MSTEAMS_CONVERSATION_TTL_MS;
144
141
  const conversationStore = createConversationStateStore(params);
145
142
  const isExpired = (reference) => {
146
- const lastSeenAt = parseStoredConversationTimestamp(reference.lastSeenAt);
143
+ const lastSeenAt = (0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(reference.lastSeenAt);
147
144
  return lastSeenAt != null && Date.now() - lastSeenAt > ttlMs;
148
145
  };
149
146
  const lookupStored = async (conversationId) => {
@@ -179,8 +176,8 @@ function createMSTeamsConversationStoreState(params) {
179
176
  }
180
177
  if (rows.length <= MSTEAMS_MAX_CONVERSATIONS) return;
181
178
  const sorted = rows.toSorted((a, b) => {
182
- const aTs = parseStoredConversationTimestamp(a.value.lastSeenAt) ?? 0;
183
- const bTs = parseStoredConversationTimestamp(b.value.lastSeenAt) ?? 0;
179
+ const aTs = (0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(a.value.lastSeenAt) ?? 0;
180
+ const bTs = (0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(b.value.lastSeenAt) ?? 0;
184
181
  const aId = getStoredConversationId(a.value) ?? a.key;
185
182
  const bId = getStoredConversationId(b.value) ?? b.key;
186
183
  return aTs - bTs || aId.localeCompare(bId);
@@ -359,13 +356,10 @@ function createPollVoteBucketStateStore(params) {
359
356
  env: resolveMSTeamsSqliteStateEnv(params)
360
357
  });
361
358
  }
362
- function parseTimestamp(value) {
363
- return (0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(value) ?? null;
364
- }
365
359
  function pruneExpired(polls) {
366
360
  const cutoff = Date.now() - MSTEAMS_POLL_TTL_MS;
367
361
  const entries = Object.entries(polls).filter(([, poll]) => {
368
- return (parseTimestamp(poll.updatedAt ?? poll.createdAt) ?? 0) >= cutoff;
362
+ return ((0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(poll.updatedAt ?? poll.createdAt) ?? 0) >= cutoff;
369
363
  });
370
364
  return Object.fromEntries(entries);
371
365
  }
@@ -373,7 +367,7 @@ function selectRetainedMSTeamsPolls(polls) {
373
367
  const retained = Object.entries(pruneExpired(polls));
374
368
  if (retained.length <= MSTEAMS_MAX_POLLS) return retained;
375
369
  retained.sort((a, b) => {
376
- return (parseTimestamp(a[1].updatedAt ?? a[1].createdAt) ?? 0) - (parseTimestamp(b[1].updatedAt ?? b[1].createdAt) ?? 0) || a[0].localeCompare(b[0]);
370
+ return ((0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(a[1].updatedAt ?? a[1].createdAt) ?? 0) - ((0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(b[1].updatedAt ?? b[1].createdAt) ?? 0) || a[0].localeCompare(b[0]);
377
371
  });
378
372
  return retained.slice(retained.length - MSTEAMS_MAX_POLLS);
379
373
  }
@@ -467,7 +461,7 @@ function createMSTeamsPollStoreState(params) {
467
461
  }
468
462
  if (rows.length <= MSTEAMS_MAX_POLLS) return;
469
463
  const sorted = rows.toSorted((a, b) => {
470
- return (parseTimestamp(a.value.updatedAt ?? a.value.createdAt) ?? 0) - (parseTimestamp(b.value.updatedAt ?? b.value.createdAt) ?? 0) || a.key.localeCompare(b.key);
464
+ return ((0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(a.value.updatedAt ?? a.value.createdAt) ?? 0) - ((0, openclaw_plugin_sdk_number_runtime.parseDateStringTimestampMs)(b.value.updatedAt ?? b.value.createdAt) ?? 0) || a.key.localeCompare(b.key);
471
465
  });
472
466
  for (const row of sorted.slice(0, rows.length - MSTEAMS_MAX_POLLS)) {
473
467
  await pollStore.delete(row.key);