@openclaw/msteams 2026.10.5-beta.4 → 2026.10.10-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/.setup/{adapter.runtime-JoPydWqP.cjs → adapter.runtime-B-6Q3nMI.cjs} +6 -4
  2. package/dist/.setup/{approval-handler.runtime-bUN9icMr.cjs → approval-handler.runtime-DccVf5AY.cjs} +16 -6
  3. package/dist/.setup/{bot-framework-service-url-CPp4d-Q6.cjs → bot-framework-service-url-B3FWn2SV.cjs} +13 -0
  4. package/dist/.setup/{channel-Cifn9fsv.cjs → channel-B7Gy3QUW.cjs} +261 -175
  5. package/dist/.setup/{channel.runtime-DWRAolil.cjs → channel.runtime-DzKeQAqd.cjs} +84 -49
  6. package/dist/.setup/channel.setup-B5ClEcNI.cjs +990 -0
  7. package/dist/.setup/config-schema-CkKdphSp.cjs +293 -0
  8. package/dist/.setup/{conversation-store-state-DprmOfl7.cjs → conversation-store-state-C3__T9mK.cjs} +79 -91
  9. package/dist/.setup/delegated-state-Bv5cWuec.cjs +110 -0
  10. package/dist/.setup/{monitor-C9x_CJhY.cjs → monitor-CzRI-Hsc.cjs} +283 -240
  11. package/dist/.setup/{oauth-CWJ85AMw.cjs → oauth-D9u8sPCD.cjs} +1 -1
  12. package/dist/.setup/{reaction-types-Ig9sQJuR.cjs → reaction-types-DSQWVA4Z.cjs} +15 -9
  13. package/dist/.setup/{resolve-allowlist-DdDBVCzl.cjs → resolve-allowlist-tYgAHx0t.cjs} +252 -38
  14. package/dist/.setup/{secret-contract-api-ChQdBeU1.cjs → secret-contract-api-YY3v6MP8.cjs} +1 -1
  15. package/dist/.setup/secret-contract-api-wAyY5UHv.cjs +85 -0
  16. package/dist/.setup/{send-rJpcVtRp.cjs → send-Bgm8RYUa.cjs} +45 -24
  17. package/dist/.setup/{setup-plugin-api-DfoVOqMJ.cjs → setup-plugin-api-BACfeF7_.cjs} +1 -1
  18. package/dist/.setup/{thread-session-B74FC1Id.cjs → thread-session-C7KTMwLU.cjs} +11 -4
  19. package/dist/.setup/token-config-bEpua_Q7.cjs +93 -0
  20. package/dist/api.cjs +2 -2
  21. package/dist/channel-config-api.cjs +1 -1
  22. package/dist/channel-plugin-api.cjs +1 -1
  23. package/dist/directory-contract-api.cjs +30 -22
  24. package/dist/doctor-contract-api.cjs +11 -10
  25. package/dist/qa-runner-api.cjs +1 -1
  26. package/dist/runtime-api.cjs +2 -2
  27. package/dist/secret-contract-api.cjs +1 -1
  28. package/dist/setup-entry.cjs +2 -2
  29. package/dist/setup-plugin-api.cjs +1 -1
  30. package/openclaw.plugin.json +715 -0
  31. package/package.json +57 -6
  32. package/dist/.setup/channel.setup-BjbHugkL.cjs +0 -632
  33. package/dist/.setup/config-schema-Dk0mRIam.cjs +0 -160
  34. package/dist/.setup/secret-contract-api-ipiUsANg.cjs +0 -28
  35. package/dist/.setup/token-config-CqIh8z7Q.cjs +0 -138
@@ -1,4 +1,4 @@
1
- const require_resolve_allowlist = require("./resolve-allowlist-DdDBVCzl.cjs");
1
+ const require_resolve_allowlist = require("./resolve-allowlist-tYgAHx0t.cjs");
2
2
  let openclaw_plugin_sdk_provider_auth = require("openclaw/plugin-sdk/provider-auth");
3
3
  let openclaw_plugin_sdk_provider_auth_runtime = require("openclaw/plugin-sdk/provider-auth-runtime");
4
4
  //#region extensions/msteams/src/oauth.flow.ts
@@ -1,5 +1,10 @@
1
- const require_resolve_allowlist = require("./resolve-allowlist-DdDBVCzl.cjs");
1
+ const require_resolve_allowlist = require("./resolve-allowlist-tYgAHx0t.cjs");
2
2
  //#region extensions/msteams/src/graph-thread.ts
3
+ /** Keep inbound thread enrichment bounded while still reaching recent replies. */
4
+ const MAX_REPLY_PAGES = 50;
5
+ function compareThreadMessagesChronologically(a, b) {
6
+ return Date.parse(a.createdDateTime ?? "") - Date.parse(b.createdDateTime ?? "") || (a.id ?? "").localeCompare(b.id ?? "");
7
+ }
3
8
  /**
4
9
  * Strip HTML tags from Teams message content, preserving @mention display names.
5
10
  * Teams wraps mentions in <at>Name</at> tags.
@@ -50,20 +55,21 @@ async function fetchChatMessageText(token, chatId, messageId, deadline) {
50
55
  /**
51
56
  * Fetch thread replies for a channel message, ordered chronologically.
52
57
  *
53
- * **Limitation:** The Graph API replies endpoint (`/messages/{id}/replies`) does not
54
- * support `$orderby`, so results are always returned in ascending (oldest-first) order.
55
- * Combined with the `$top` cap of 50, this means only the **oldest 50 replies** are
56
- * returned for long threads — newer replies are silently omitted. There is currently no
57
- * Graph API workaround for this; pagination via `@odata.nextLink` can retrieve more
58
- * replies but still in ascending order only.
58
+ * Graph caps each replies page at 50 and does not support `$orderby`. Follow
59
+ * `@odata.nextLink`, then return the newest bounded window in chronological order.
59
60
  */
60
61
  async function fetchThreadReplies(token, groupId, channelId, messageId, deadline) {
61
62
  const path = `/teams/${encodeURIComponent(groupId)}/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}/replies?$top=50`;
62
- return (await require_resolve_allowlist.fetchGraphJson({
63
+ const { items, truncated } = await require_resolve_allowlist.fetchAllGraphPages({
63
64
  token,
64
65
  path,
66
+ maxPages: MAX_REPLY_PAGES,
65
67
  ...deadline ? { deadline } : {}
66
- })).value ?? [];
68
+ });
69
+ if (truncated) throw new Error("MS Teams thread replies pagination did not reach the newest replies");
70
+ if (items.length <= 50) return items;
71
+ if (!items.every((item) => Number.isFinite(Date.parse(item.createdDateTime ?? "")))) throw new Error("MS Teams thread replies have incomplete timestamps");
72
+ return items.toSorted(compareThreadMessagesChronologically).slice(-50);
67
73
  }
68
74
  function buildThreadContext(messages, currentMessageId) {
69
75
  const context = [];
@@ -1,9 +1,13 @@
1
+ const require_bot_framework_service_url = require("./bot-framework-service-url-B3FWn2SV.cjs");
2
+ const require_token_config = require("./token-config-bEpua_Q7.cjs");
1
3
  const require_runtime = require("./runtime-gZTAuFux.cjs");
2
4
  require("../runtime-api.cjs");
3
- const require_bot_framework_service_url = require("./bot-framework-service-url-CPp4d-Q6.cjs");
4
- const require_token_config = require("./token-config-CqIh8z7Q.cjs");
5
+ const require_delegated_state = require("./delegated-state-Bv5cWuec.cjs");
5
6
  let openclaw_plugin_sdk_lazy_runtime = require("openclaw/plugin-sdk/lazy-runtime");
6
7
  let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
8
+ let openclaw_plugin_sdk_account_helpers = require("openclaw/plugin-sdk/account-helpers");
9
+ let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
10
+ let openclaw_plugin_sdk_secret_file_runtime = require("openclaw/plugin-sdk/secret-file-runtime");
7
11
  let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
8
12
  let node_async_hooks = require("node:async_hooks");
9
13
  let openclaw_plugin_sdk_fetch_runtime = require("openclaw/plugin-sdk/fetch-runtime");
@@ -18,21 +22,177 @@ let openclaw_plugin_sdk_secret_file = require("openclaw/plugin-sdk/secret-file")
18
22
  let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
19
23
  let node_module = require("node:module");
20
24
  let openclaw_plugin_sdk_html_entity_runtime = require("openclaw/plugin-sdk/html-entity-runtime");
25
+ //#region extensions/msteams/src/accounts.ts
26
+ const { listAccountIds, resolveDefaultAccountId } = (0, openclaw_plugin_sdk_account_helpers.createAccountListHelpers)("msteams", {
27
+ normalizeAccountId: openclaw_plugin_sdk_account_id.normalizeAccountId,
28
+ hasImplicitDefaultAccount: (cfg) => require_token_config.hasConfiguredMSTeamsCredentials(cfg.channels?.msteams)
29
+ });
30
+ const listMSTeamsAccountIds = listAccountIds;
31
+ const resolveDefaultMSTeamsAccountId = resolveDefaultAccountId;
32
+ function withAccountScopedMSTeamsConfig(params) {
33
+ return {
34
+ ...params.cfg,
35
+ channels: {
36
+ ...params.cfg.channels,
37
+ msteams: params.accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID ? params.accountConfig : {
38
+ ...params.accountConfig,
39
+ defaultAccount: params.accountId
40
+ }
41
+ }
42
+ };
43
+ }
44
+ function accountDefinesIdentity(account) {
45
+ return Boolean(account?.appId || account?.appPassword);
46
+ }
47
+ function resolveMSTeamsAccountEntry(accounts, accountId) {
48
+ const key = resolveMSTeamsAccountEntryKey(accounts, accountId);
49
+ return key ? accounts?.[key] : void 0;
50
+ }
51
+ function resolveMSTeamsAccountEntryKey(accounts, accountId) {
52
+ if (!accounts) return;
53
+ for (const key of Object.keys(accounts)) if ((0, openclaw_plugin_sdk_account_id.normalizeAccountId)(key) === accountId) return key;
54
+ }
55
+ function resolveMSTeamsAccountConfigPath(cfg, accountId) {
56
+ const normalized = (0, openclaw_plugin_sdk_account_id.normalizeAccountId)(accountId);
57
+ const rawAccountKey = resolveMSTeamsAccountEntryKey(cfg.channels?.msteams?.accounts, normalized);
58
+ if (rawAccountKey) return `channels.msteams.accounts.${rawAccountKey}`;
59
+ return normalized === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID ? "channels.msteams" : `channels.msteams.accounts.${normalized}`;
60
+ }
61
+ function isAccountScopedChannelConfig(channelConfig, accountId) {
62
+ if (!channelConfig) return false;
63
+ const accounts = channelConfig.accounts;
64
+ return (0, openclaw_plugin_sdk_account_id.normalizeAccountId)(channelConfig.defaultAccount) === accountId && (!accounts || Object.keys(accounts).length === 0) && accountDefinesIdentity(channelConfig);
65
+ }
66
+ function clearNamedAccountInheritedIdentity(merged, account) {
67
+ const next = { ...merged };
68
+ if (account?.appId === void 0) delete next.appId;
69
+ if (account?.appPassword === void 0) delete next.appPassword;
70
+ if (account?.legacyWebhook === void 0) delete next.legacyWebhook;
71
+ return next;
72
+ }
73
+ function resolveMSTeamsAccountConfig(cfg, accountId) {
74
+ const resolvedAccountId = (0, openclaw_plugin_sdk_account_id.normalizeAccountId)(accountId ?? resolveDefaultMSTeamsAccountId(cfg));
75
+ const channelConfig = cfg.channels?.msteams;
76
+ const account = resolveMSTeamsAccountEntry(channelConfig?.accounts, resolvedAccountId);
77
+ const merged = (0, openclaw_plugin_sdk_account_helpers.resolveMergedAccountConfig)({
78
+ channelConfig,
79
+ accounts: channelConfig?.accounts,
80
+ accountId: resolvedAccountId,
81
+ normalizeAccountId: openclaw_plugin_sdk_account_id.normalizeAccountId,
82
+ omitKeys: ["defaultAccount"],
83
+ nestedObjectKeys: [
84
+ "webhook",
85
+ "markdown",
86
+ "streaming",
87
+ "blockStreamingCoalesce",
88
+ "dms",
89
+ "teams",
90
+ "heartbeat",
91
+ "healthMonitor",
92
+ "delegatedAuth",
93
+ "sso"
94
+ ]
95
+ });
96
+ if (resolvedAccountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID || !account && isAccountScopedChannelConfig(channelConfig, resolvedAccountId)) return merged;
97
+ const config = clearNamedAccountInheritedIdentity(merged, account);
98
+ return {
99
+ ...config,
100
+ webhook: {
101
+ ...config.webhook,
102
+ path: require_bot_framework_service_url.resolveMSTeamsWebhookPath(channelConfig, resolvedAccountId, account)
103
+ }
104
+ };
105
+ }
106
+ function resolveMSTeamsRuntimeAccount(params) {
107
+ const accountId = (0, openclaw_plugin_sdk_account_id.normalizeAccountId)(params.accountId ?? resolveDefaultMSTeamsAccountId(params.cfg));
108
+ const config = params.msteamsCfg ?? resolveMSTeamsAccountConfig(params.cfg, accountId);
109
+ return {
110
+ accountId,
111
+ config,
112
+ credentials: require_token_config.resolveMSTeamsCredentials(config, {
113
+ allowEnvFallback: accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID,
114
+ pathPrefix: resolveMSTeamsAccountConfigPath(params.cfg, accountId)
115
+ })
116
+ };
117
+ }
118
+ function resolveMSTeamsAccountWithMode(params) {
119
+ const accountId = (0, openclaw_plugin_sdk_account_id.normalizeAccountId)(params.accountId ?? resolveDefaultMSTeamsAccountId(params.cfg));
120
+ const channelEnabled = params.cfg.channels?.msteams?.enabled !== false;
121
+ const config = resolveMSTeamsAccountConfig(params.cfg, accountId);
122
+ const accountEnabled = config.enabled !== false;
123
+ const pathPrefix = resolveMSTeamsAccountConfigPath(params.cfg, accountId);
124
+ const credentialResolution = params.mode === "inspect" ? require_token_config.inspectMSTeamsCredentials(config, { allowEnvFallback: accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID }) : (() => {
125
+ const credentials = require_token_config.resolveMSTeamsCredentials(config, {
126
+ allowEnvFallback: accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID,
127
+ pathPrefix
128
+ });
129
+ return {
130
+ credentials,
131
+ status: credentials ? "available" : "missing"
132
+ };
133
+ })();
134
+ const credentials = credentialResolution.credentials;
135
+ const certificatePath = credentials?.type === "federated" && !credentials.useManagedIdentity ? credentials.certificatePath : void 0;
136
+ const channelConfig = params.cfg.channels?.msteams;
137
+ const rawAccountKey = resolveMSTeamsAccountEntryKey(channelConfig?.accounts, accountId);
138
+ const certificateConfigPath = (rawAccountKey ? channelConfig?.accounts?.[rawAccountKey] : void 0)?.certificatePath?.trim() ? `channels.msteams.accounts.${rawAccountKey}.certificatePath` : channelConfig?.certificatePath?.trim() ? "channels.msteams.certificatePath" : "env.MSTEAMS_CERTIFICATE_PATH";
139
+ const certificate = certificatePath ? (0, openclaw_plugin_sdk_secret_file_runtime.tryReadSecretFileSync)(certificatePath, "Microsoft Teams certificate", void 0, { configPath: certificateConfigPath }) : void 0;
140
+ const unavailable = credentialResolution.status === "configured_unavailable" || certificate?.status === "configured_unavailable";
141
+ const credentialDiagnostics = certificate?.status === "configured_unavailable" ? [certificate.diagnostic] : void 0;
142
+ return {
143
+ accountId,
144
+ enabled: channelEnabled && accountEnabled,
145
+ configured: credentialResolution.status !== "missing",
146
+ tokenStatus: credentialResolution.status === "missing" ? "missing" : unavailable ? "configured_unavailable" : "available",
147
+ ...credentialDiagnostics ? { credentialDiagnostics } : {},
148
+ config
149
+ };
150
+ }
151
+ function resolveMSTeamsAccount(params) {
152
+ return resolveMSTeamsAccountWithMode({
153
+ ...params,
154
+ mode: "runtime"
155
+ });
156
+ }
157
+ function inspectMSTeamsAccount(params) {
158
+ const account = resolveMSTeamsAccountWithMode({
159
+ ...params,
160
+ mode: "inspect"
161
+ });
162
+ return {
163
+ accountId: account.accountId,
164
+ enabled: account.enabled,
165
+ configured: account.configured,
166
+ tokenStatus: account.tokenStatus,
167
+ ...account.credentialDiagnostics ? { credentialDiagnostics: account.credentialDiagnostics } : {},
168
+ hasIdentity: account.accountId === openclaw_plugin_sdk_account_id.DEFAULT_ACCOUNT_ID || accountDefinesIdentity(resolveMSTeamsAccountEntry(params.cfg.channels?.msteams?.accounts, account.accountId)),
169
+ path: account.config.webhook?.path ?? "/api/messages"
170
+ };
171
+ }
172
+ //#endregion
21
173
  //#region extensions/msteams/src/request-timeout.ts
22
174
  const MSTEAMS_REQUEST_TIMEOUT_MS = 3e4;
23
175
  const MSTEAMS_SHAREPOINT_UPLOAD_BASE_TIMEOUT_MS = 3e5;
24
176
  const MSTEAMS_SHAREPOINT_UPLOAD_MIN_BYTES_PER_SECOND = 262144;
25
- const MSTEAMS_INBOUND_PREPROCESS_TIMEOUT_MS = 1e4;
26
- function createMSTeamsInboundDeadline() {
177
+ const MSTEAMS_INBOUND_ENRICHMENT_TIMEOUT_MS = 1e4;
178
+ const MSTEAMS_INBOUND_MEDIA_TIMEOUT_MS = 12e4;
179
+ function createMSTeamsInboundEnrichmentDeadline() {
27
180
  return (0, openclaw_plugin_sdk_provider_http.createProviderOperationDeadline)({
28
181
  label: "MS Teams inbound preprocessing",
29
- timeoutMs: MSTEAMS_INBOUND_PREPROCESS_TIMEOUT_MS
182
+ timeoutMs: MSTEAMS_INBOUND_ENRICHMENT_TIMEOUT_MS
30
183
  });
31
184
  }
185
+ function createMSTeamsInboundMediaDeadline() {
186
+ return (0, openclaw_plugin_sdk_provider_http.createProviderOperationDeadline)({
187
+ label: "MS Teams inbound media",
188
+ timeoutMs: MSTEAMS_INBOUND_MEDIA_TIMEOUT_MS
189
+ });
190
+ }
191
+ /** Per-request timeout: the operation deadline's remaining budget, else the default request cap. */
32
192
  function resolveMSTeamsRequestTimeoutMs(deadline) {
33
193
  return deadline ? (0, openclaw_plugin_sdk_provider_http.resolveProviderOperationTimeoutMs)({
34
194
  deadline,
35
- defaultTimeoutMs: MSTEAMS_REQUEST_TIMEOUT_MS
195
+ defaultTimeoutMs: deadline.timeoutMs ?? 3e4
36
196
  }) : MSTEAMS_REQUEST_TIMEOUT_MS;
37
197
  }
38
198
  /** Bound non-abortable SDK and credential work to the same operation deadline as fetches. */
@@ -41,7 +201,7 @@ async function withMSTeamsRequestDeadline(params) {
41
201
  return await (0, openclaw_plugin_sdk_text_utility_runtime.withTimeout)(params.work(), timeoutMs, params.label);
42
202
  }
43
203
  function resolveMSTeamsSharePointUploadTimeoutMs(sizeInBytes) {
44
- const transferBudgetMs = Math.ceil((Number.isFinite(sizeInBytes) && sizeInBytes > 0 ? Math.ceil(sizeInBytes) : 0) / MSTEAMS_SHAREPOINT_UPLOAD_MIN_BYTES_PER_SECOND * 1e3);
204
+ const transferBudgetMs = Math.ceil(sizeInBytes / MSTEAMS_SHAREPOINT_UPLOAD_MIN_BYTES_PER_SECOND * 1e3);
45
205
  return (0, openclaw_plugin_sdk_number_runtime.resolveTimerTimeoutMs)(MSTEAMS_SHAREPOINT_UPLOAD_BASE_TIMEOUT_MS + transferBudgetMs, MSTEAMS_SHAREPOINT_UPLOAD_BASE_TIMEOUT_MS, 1);
46
206
  }
47
207
  function createMSTeamsRequestTimeoutError(label, timeoutMs) {
@@ -689,7 +849,7 @@ async function refreshMSTeamsDelegatedTokens(params) {
689
849
  //#endregion
690
850
  //#region extensions/msteams/src/token.ts
691
851
  async function resolveDelegatedAccessToken(params) {
692
- const tokens = await require_token_config.loadMSTeamsDelegatedTokens();
852
+ const tokens = await require_delegated_state.loadMSTeamsDelegatedTokens(params.accountId);
693
853
  if (!tokens) return;
694
854
  if ((0, openclaw_plugin_sdk_number_runtime.isFutureDateTimestampMs)(tokens.expiresAt)) return tokens.accessToken;
695
855
  try {
@@ -700,7 +860,7 @@ async function resolveDelegatedAccessToken(params) {
700
860
  refreshToken: tokens.refreshToken,
701
861
  scopes: tokens.scopes
702
862
  });
703
- await require_token_config.saveMSTeamsDelegatedTokens(refreshed);
863
+ await require_delegated_state.saveMSTeamsDelegatedTokens(refreshed, params.accountId);
704
864
  return refreshed.accessToken;
705
865
  } catch {
706
866
  return;
@@ -733,7 +893,7 @@ async function requestGraph(params) {
733
893
  const assertRequestCurrent = captureGraphRequestCurrentness(assertReadAuthority);
734
894
  assertRequestCurrent?.();
735
895
  const hasBody = params.body !== void 0;
736
- const url = `${params.root ?? "https://graph.microsoft.com/v1.0"}${params.path}`;
896
+ const url = params.absoluteUrl ?? `${params.root ?? "https://graph.microsoft.com/v1.0"}${params.path}`;
737
897
  const { response, release } = await (0, openclaw_plugin_sdk_ssrf_runtime.fetchWithSsrFGuard)({
738
898
  url,
739
899
  init: {
@@ -746,7 +906,7 @@ async function requestGraph(params) {
746
906
  },
747
907
  body: hasBody ? JSON.stringify(params.body) : void 0
748
908
  },
749
- auditContext: "msteams.graph",
909
+ auditContext: params.absoluteUrl ? "msteams.graph.absolute" : "msteams.graph",
750
910
  timeoutMs: resolveMSTeamsRequestTimeoutMs(params.deadline),
751
911
  beforeRequest: assertRequestCurrent
752
912
  });
@@ -794,28 +954,15 @@ async function fetchGraphJson(params) {
794
954
  */
795
955
  async function fetchGraphAbsoluteUrl(params) {
796
956
  const assertReadAuthority = (0, openclaw_plugin_sdk_fetch_runtime.captureChannelReadAuthority)();
797
- const assertRequestCurrent = captureGraphRequestCurrentness(assertReadAuthority);
798
- assertRequestCurrent?.();
799
- const { response, release } = await (0, openclaw_plugin_sdk_ssrf_runtime.fetchWithSsrFGuard)({
800
- url: params.url,
801
- init: { headers: {
802
- "User-Agent": buildUserAgent(),
803
- Authorization: `Bearer ${params.token}`
804
- } },
805
- auditContext: "msteams.graph.absolute",
806
- timeoutMs: MSTEAMS_REQUEST_TIMEOUT_MS,
807
- beforeRequest: assertRequestCurrent
808
- });
809
957
  try {
810
- assertReadAuthority?.();
811
- if (!response.ok) throw await (0, openclaw_plugin_sdk_provider_http.createProviderHttpError)(response, `Graph ${params.url} failed`);
958
+ const response = await requestGraph({
959
+ token: params.token,
960
+ path: params.url,
961
+ absoluteUrl: params.url
962
+ });
812
963
  return await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(response, `Graph ${params.url} failed`);
813
964
  } finally {
814
- try {
815
- await release();
816
- } finally {
817
- assertReadAuthority?.();
818
- }
965
+ assertReadAuthority?.();
819
966
  }
820
967
  }
821
968
  async function fetchAllGraphPages(params) {
@@ -826,7 +973,8 @@ async function fetchAllGraphPages(params) {
826
973
  const res = await fetchGraphJson({
827
974
  token: params.token,
828
975
  path: nextPath,
829
- headers: params.headers
976
+ headers: params.headers,
977
+ ...params.deadline ? { deadline: params.deadline } : {}
830
978
  });
831
979
  const pageItems = res.value ?? [];
832
980
  const match = params.findOne ? pageItems.find(params.findOne) : void 0;
@@ -848,15 +996,20 @@ async function fetchAllGraphPages(params) {
848
996
  async function resolveGraphToken(cfg, options) {
849
997
  const assertRequestCurrent = captureGraphRequestCurrentness((0, openclaw_plugin_sdk_fetch_runtime.captureChannelReadAuthority)());
850
998
  assertRequestCurrent?.();
851
- const msteamsCfg = cfg?.channels?.msteams;
852
- const creds = require_token_config.resolveMSTeamsCredentials(msteamsCfg);
999
+ const openClawCfg = cfg;
1000
+ const { accountId, config: msteamsCfg, credentials: creds } = resolveMSTeamsRuntimeAccount({
1001
+ cfg: openClawCfg,
1002
+ accountId: options?.accountId
1003
+ });
1004
+ if (openClawCfg.channels?.msteams?.enabled === false || msteamsCfg.enabled === false) throw new Error("MS Teams account disabled: " + accountId);
853
1005
  if (!creds) throw new Error("MS Teams credentials missing");
854
1006
  if (msteamsCfg?.cloud === "China") throw new Error("Microsoft Teams Graph operations are not supported for channels.msteams.cloud=China until Graph requests are routed through the Azure China Graph endpoint.");
855
1007
  if (options?.preferDelegated && msteamsCfg?.delegatedAuth?.enabled && creds.type === "secret") {
856
1008
  const delegated = await resolveDelegatedAccessToken({
857
1009
  tenantId: creds.tenantId,
858
1010
  clientId: creds.appId,
859
- clientSecret: creds.appPassword
1011
+ clientSecret: creds.appPassword,
1012
+ accountId
860
1013
  });
861
1014
  assertRequestCurrent?.();
862
1015
  if (delegated) return delegated;
@@ -1145,7 +1298,7 @@ function parseMSTeamsTeamEntry(raw) {
1145
1298
  async function resolveMSTeamsChannelAllowlist(params) {
1146
1299
  let tokenPromise;
1147
1300
  const getToken = () => {
1148
- tokenPromise ??= resolveGraphToken(params.cfg);
1301
+ tokenPromise ??= resolveGraphToken(params.cfg, { accountId: params.accountId });
1149
1302
  return tokenPromise;
1150
1303
  };
1151
1304
  return await (0, openclaw_plugin_sdk_allow_from.mapAllowlistResolutionInputs)({
@@ -1313,6 +1466,7 @@ async function resolveMSTeamsTeamsConfig(params) {
1313
1466
  };
1314
1467
  const resolved = await resolveMSTeamsChannelAllowlist({
1315
1468
  cfg: params.cfg,
1469
+ accountId: params.accountId,
1316
1470
  entries: entries.map((entry) => entry.input),
1317
1471
  teamIdMode: params.teamIdMode
1318
1472
  });
@@ -1363,7 +1517,7 @@ async function resolveMSTeamsTeamsConfig(params) {
1363
1517
  async function resolveMSTeamsUserAllowlist(params) {
1364
1518
  let tokenPromise;
1365
1519
  const getToken = () => {
1366
- tokenPromise ??= resolveGraphToken(params.cfg);
1520
+ tokenPromise ??= resolveGraphToken(params.cfg, { accountId: params.accountId });
1367
1521
  return tokenPromise;
1368
1522
  };
1369
1523
  return await (0, openclaw_plugin_sdk_allow_from.mapAllowlistResolutionInputs)({
@@ -1480,10 +1634,16 @@ Object.defineProperty(exports, "createMSTeamsExpressAdapter", {
1480
1634
  return createMSTeamsExpressAdapter;
1481
1635
  }
1482
1636
  });
1483
- Object.defineProperty(exports, "createMSTeamsInboundDeadline", {
1637
+ Object.defineProperty(exports, "createMSTeamsInboundEnrichmentDeadline", {
1638
+ enumerable: true,
1639
+ get: function() {
1640
+ return createMSTeamsInboundEnrichmentDeadline;
1641
+ }
1642
+ });
1643
+ Object.defineProperty(exports, "createMSTeamsInboundMediaDeadline", {
1484
1644
  enumerable: true,
1485
1645
  get: function() {
1486
- return createMSTeamsInboundDeadline;
1646
+ return createMSTeamsInboundMediaDeadline;
1487
1647
  }
1488
1648
  });
1489
1649
  Object.defineProperty(exports, "createMSTeamsTokenProvider", {
@@ -1570,6 +1730,12 @@ Object.defineProperty(exports, "htmlToPlainText", {
1570
1730
  return htmlToPlainText;
1571
1731
  }
1572
1732
  });
1733
+ Object.defineProperty(exports, "inspectMSTeamsAccount", {
1734
+ enumerable: true,
1735
+ get: function() {
1736
+ return inspectMSTeamsAccount;
1737
+ }
1738
+ });
1573
1739
  Object.defineProperty(exports, "isAdvertisedFileAttachment", {
1574
1740
  enumerable: true,
1575
1741
  get: function() {
@@ -1606,6 +1772,12 @@ Object.defineProperty(exports, "listChannelsForTeamWithPageInfo", {
1606
1772
  return listChannelsForTeamWithPageInfo;
1607
1773
  }
1608
1774
  });
1775
+ Object.defineProperty(exports, "listMSTeamsAccountIds", {
1776
+ enumerable: true,
1777
+ get: function() {
1778
+ return listMSTeamsAccountIds;
1779
+ }
1780
+ });
1609
1781
  Object.defineProperty(exports, "listTeamsByName", {
1610
1782
  enumerable: true,
1611
1783
  get: function() {
@@ -1714,12 +1886,42 @@ Object.defineProperty(exports, "resolveAttachmentFetchPolicy", {
1714
1886
  return resolveAttachmentFetchPolicy;
1715
1887
  }
1716
1888
  });
1889
+ Object.defineProperty(exports, "resolveDefaultMSTeamsAccountId", {
1890
+ enumerable: true,
1891
+ get: function() {
1892
+ return resolveDefaultMSTeamsAccountId;
1893
+ }
1894
+ });
1717
1895
  Object.defineProperty(exports, "resolveGraphToken", {
1718
1896
  enumerable: true,
1719
1897
  get: function() {
1720
1898
  return resolveGraphToken;
1721
1899
  }
1722
1900
  });
1901
+ Object.defineProperty(exports, "resolveMSTeamsAccount", {
1902
+ enumerable: true,
1903
+ get: function() {
1904
+ return resolveMSTeamsAccount;
1905
+ }
1906
+ });
1907
+ Object.defineProperty(exports, "resolveMSTeamsAccountConfig", {
1908
+ enumerable: true,
1909
+ get: function() {
1910
+ return resolveMSTeamsAccountConfig;
1911
+ }
1912
+ });
1913
+ Object.defineProperty(exports, "resolveMSTeamsAccountConfigPath", {
1914
+ enumerable: true,
1915
+ get: function() {
1916
+ return resolveMSTeamsAccountConfigPath;
1917
+ }
1918
+ });
1919
+ Object.defineProperty(exports, "resolveMSTeamsAccountEntryKey", {
1920
+ enumerable: true,
1921
+ get: function() {
1922
+ return resolveMSTeamsAccountEntryKey;
1923
+ }
1924
+ });
1723
1925
  Object.defineProperty(exports, "resolveMSTeamsChannelAllowlist", {
1724
1926
  enumerable: true,
1725
1927
  get: function() {
@@ -1744,6 +1946,12 @@ Object.defineProperty(exports, "resolveMSTeamsRequestTimeoutMs", {
1744
1946
  return resolveMSTeamsRequestTimeoutMs;
1745
1947
  }
1746
1948
  });
1949
+ Object.defineProperty(exports, "resolveMSTeamsRuntimeAccount", {
1950
+ enumerable: true,
1951
+ get: function() {
1952
+ return resolveMSTeamsRuntimeAccount;
1953
+ }
1954
+ });
1747
1955
  Object.defineProperty(exports, "resolveMSTeamsSdkCloudOptions", {
1748
1956
  enumerable: true,
1749
1957
  get: function() {
@@ -1816,6 +2024,12 @@ Object.defineProperty(exports, "wasMSTeamsBotMentioned", {
1816
2024
  return wasMSTeamsBotMentioned;
1817
2025
  }
1818
2026
  });
2027
+ Object.defineProperty(exports, "withAccountScopedMSTeamsConfig", {
2028
+ enumerable: true,
2029
+ get: function() {
2030
+ return withAccountScopedMSTeamsConfig;
2031
+ }
2032
+ });
1819
2033
  Object.defineProperty(exports, "withMSTeamsAbortableRequestTimeout", {
1820
2034
  enumerable: true,
1821
2035
  get: function() {
@@ -1,4 +1,4 @@
1
- const require_secret_contract_api = require("./secret-contract-api-ipiUsANg.cjs");
1
+ const require_secret_contract_api = require("./secret-contract-api-wAyY5UHv.cjs");
2
2
  exports.channelSecrets = require_secret_contract_api.channelSecrets;
3
3
  exports.collectRuntimeConfigAssignments = require_secret_contract_api.collectRuntimeConfigAssignments;
4
4
  exports.secretTargetRegistryEntries = require_secret_contract_api.secretTargetRegistryEntries;
@@ -0,0 +1,85 @@
1
+ let openclaw_plugin_sdk_setup = require("openclaw/plugin-sdk/setup");
2
+ let openclaw_plugin_sdk_channel_secret_basic_runtime = require("openclaw/plugin-sdk/channel-secret-basic-runtime");
3
+ //#region extensions/msteams/src/secret-contract.ts
4
+ const secretTargetRegistryEntries = (0, openclaw_plugin_sdk_channel_secret_basic_runtime.createChannelSecretTargetRegistryEntries)({
5
+ channelKey: "msteams",
6
+ account: ["appPassword"],
7
+ channel: ["appPassword"]
8
+ });
9
+ function collectRuntimeConfigAssignments(params) {
10
+ const resolved = (0, openclaw_plugin_sdk_channel_secret_basic_runtime.getChannelSurface)(params.config, "msteams");
11
+ if (!resolved) return;
12
+ const { channel: msteams, surface } = resolved;
13
+ (0, openclaw_plugin_sdk_channel_secret_basic_runtime.collectSecretInputAssignment)({
14
+ value: msteams.appPassword,
15
+ path: "channels.msteams.appPassword",
16
+ expected: "string",
17
+ defaults: params.defaults,
18
+ context: params.context,
19
+ active: isRootDefaultIdentityActive(msteams, surface),
20
+ inactiveReason: "no enabled account inherits this top-level Microsoft Teams appPassword.",
21
+ owner: {
22
+ ownerKind: "account",
23
+ ownerId: "msteams:default",
24
+ requiredForGateway: false,
25
+ disposition: "isolate",
26
+ contract: msteams
27
+ },
28
+ apply: (value) => {
29
+ msteams.appPassword = value;
30
+ }
31
+ });
32
+ if (!surface.hasExplicitAccounts) return;
33
+ for (const { accountId, account, enabled } of surface.accounts) {
34
+ if (!(0, openclaw_plugin_sdk_channel_secret_basic_runtime.hasOwnProperty)(account, "appPassword")) continue;
35
+ (0, openclaw_plugin_sdk_channel_secret_basic_runtime.collectSecretInputAssignment)({
36
+ value: account.appPassword,
37
+ path: `channels.msteams.accounts.${accountId}.appPassword`,
38
+ expected: "string",
39
+ defaults: params.defaults,
40
+ context: params.context,
41
+ active: enabled,
42
+ inactiveReason: "Microsoft Teams account is disabled.",
43
+ owner: {
44
+ ownerKind: "account",
45
+ ownerId: `msteams:${(0, openclaw_plugin_sdk_setup.normalizeAccountId)(accountId)}`,
46
+ requiredForGateway: false,
47
+ disposition: "isolate",
48
+ contract: account
49
+ },
50
+ apply: (value) => {
51
+ account.appPassword = value;
52
+ }
53
+ });
54
+ }
55
+ }
56
+ function isConfiguredIdentityField(value) {
57
+ if (typeof value === "string") return value.trim().length > 0;
58
+ return value !== void 0 && value !== null;
59
+ }
60
+ function isRootDefaultIdentityActive(channel, surface) {
61
+ return ((surface.hasExplicitAccounts ? surface.accounts.find(({ accountId }) => (0, openclaw_plugin_sdk_setup.normalizeAccountId)(accountId) === openclaw_plugin_sdk_setup.DEFAULT_ACCOUNT_ID) : void 0)?.enabled ?? surface.channelEnabled) && (isConfiguredIdentityField(channel.appId) || isConfiguredIdentityField(channel.appPassword));
62
+ }
63
+ const channelSecrets = {
64
+ secretTargetRegistryEntries,
65
+ collectRuntimeConfigAssignments
66
+ };
67
+ //#endregion
68
+ Object.defineProperty(exports, "channelSecrets", {
69
+ enumerable: true,
70
+ get: function() {
71
+ return channelSecrets;
72
+ }
73
+ });
74
+ Object.defineProperty(exports, "collectRuntimeConfigAssignments", {
75
+ enumerable: true,
76
+ get: function() {
77
+ return collectRuntimeConfigAssignments;
78
+ }
79
+ });
80
+ Object.defineProperty(exports, "secretTargetRegistryEntries", {
81
+ enumerable: true,
82
+ get: function() {
83
+ return secretTargetRegistryEntries;
84
+ }
85
+ });