@openclaw/msteams 2026.8.1-beta.3 → 2026.8.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.
- package/dist/{adapter.runtime-8g-MOPfb.cjs → adapter.runtime-DDuc7sKJ.cjs} +1 -1
- package/dist/api.cjs +2 -2
- package/dist/approval-card-BEblaIto.cjs +303 -0
- package/dist/approval-handler.runtime-C0AWNWXk.cjs +107 -0
- package/dist/{channel-KpWENcgK.cjs → channel-DLn4b6Qi.cjs} +168 -53
- package/dist/channel-config-api.cjs +1 -1
- package/dist/channel-plugin-api.cjs +1 -1
- package/dist/{channel.runtime-Bkzj8jZ0.cjs → channel.runtime-1mH99ZAm.cjs} +49 -608
- package/dist/{channel.setup-mOFtsfYz.cjs → channel.setup-BRbhaigB.cjs} +29 -18
- package/dist/{config-schema-C4CszdDi.cjs → config-schema-MyN2lamA.cjs} +12 -11
- package/dist/configured-state.cjs +20 -0
- package/dist/directory-contract-api.cjs +1 -1
- package/dist/doctor-contract-api.cjs +79 -42
- package/dist/{messenger-IISPSOvj.cjs → messenger-flkiAkkB.cjs} +29 -171
- package/dist/{oauth-C9So7uld.cjs → oauth-Bctn-WPI.cjs} +4 -3
- package/dist/{polls-DvuJvaDG.cjs → polls-P86qBpeV.cjs} +5 -4
- package/dist/qa-runner-api.cjs +1 -1
- package/dist/reaction-types-CL79V_5D.cjs +150 -0
- package/dist/{resolve-allowlist-CIfWUwuc.cjs → resolve-allowlist-BrdWKHE-.cjs} +26 -51
- package/dist/{rolldown-runtime-D6vf50IK.cjs → rolldown-runtime-VH7oDXx4.cjs} +1 -1
- package/dist/runtime-api.cjs +2 -1
- package/dist/secret-input-C65t6kjM.cjs +1 -0
- package/dist/send-C4BjzS1F.cjs +631 -0
- package/dist/setup-plugin-api.cjs +1 -1
- package/dist/{src-C127-DcQ.cjs → src-RSjkJRjI.cjs} +237 -99
- package/dist/{sso-token-store-ChhO1f4i.cjs → sso-token-store-CNbRhz-A.cjs} +1 -1
- package/dist/thread-session-DxOri69r.cjs +63 -0
- package/package.json +13 -11
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
const require_rolldown_runtime = require("./rolldown-runtime-
|
|
1
|
+
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
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
5
|
-
const require_channel_setup = require("./channel.setup-
|
|
6
|
-
const require_polls = require("./polls-
|
|
4
|
+
const require_resolve_allowlist = require("./resolve-allowlist-BrdWKHE-.cjs");
|
|
5
|
+
const require_channel_setup = require("./channel.setup-BRbhaigB.cjs");
|
|
6
|
+
const require_polls = require("./polls-P86qBpeV.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");
|
|
@@ -12,123 +12,17 @@ let openclaw_plugin_sdk_text_chunking = require("openclaw/plugin-sdk/text-chunki
|
|
|
12
12
|
let node_dns_promises = require("node:dns/promises");
|
|
13
13
|
let openclaw_plugin_sdk_ssrf_policy = require("openclaw/plugin-sdk/ssrf-policy");
|
|
14
14
|
let openclaw_plugin_sdk_text_utility_runtime = require("openclaw/plugin-sdk/text-utility-runtime");
|
|
15
|
-
let openclaw_plugin_sdk_html_entity_runtime = require("openclaw/plugin-sdk/html-entity-runtime");
|
|
16
15
|
let openclaw_plugin_sdk_retry_runtime = require("openclaw/plugin-sdk/retry-runtime");
|
|
17
16
|
let node_crypto = require("node:crypto");
|
|
18
17
|
node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
|
|
19
18
|
let node_path = require("node:path");
|
|
20
19
|
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
20
|
+
let openclaw_plugin_sdk_runtime_env = require("openclaw/plugin-sdk/runtime-env");
|
|
21
21
|
let openclaw_plugin_sdk_global_singleton = require("openclaw/plugin-sdk/global-singleton");
|
|
22
22
|
let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
|
|
23
23
|
let openclaw_plugin_sdk_reply_chunking = require("openclaw/plugin-sdk/reply-chunking");
|
|
24
|
-
let openclaw_plugin_sdk_runtime_env = require("openclaw/plugin-sdk/runtime-env");
|
|
25
24
|
let openclaw_plugin_sdk_web_media = require("openclaw/plugin-sdk/web-media");
|
|
26
25
|
let openclaw_plugin_sdk_media_runtime = require("openclaw/plugin-sdk/media-runtime");
|
|
27
|
-
//#region extensions/msteams/src/graph-thread.ts
|
|
28
|
-
/**
|
|
29
|
-
* Strip HTML tags from Teams message content, preserving @mention display names.
|
|
30
|
-
* Teams wraps mentions in <at>Name</at> tags.
|
|
31
|
-
*/
|
|
32
|
-
function stripHtmlFromTeamsMessage(html) {
|
|
33
|
-
let text = html.replace(/<at[^>]*>(.*?)<\/at>/gi, "@$1");
|
|
34
|
-
text = text.replace(/<[^>]*>/g, " ");
|
|
35
|
-
text = (0, openclaw_plugin_sdk_html_entity_runtime.decodeHtmlEntities)(text).replaceAll("\xA0", " ");
|
|
36
|
-
return text.replace(/\s+/g, " ").trim();
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Fetch a single channel message (the parent/root of a thread).
|
|
40
|
-
* Returns undefined on error so callers can degrade gracefully.
|
|
41
|
-
*/
|
|
42
|
-
async function fetchChannelMessage(token, groupId, channelId, messageId, deadline) {
|
|
43
|
-
const path = `/teams/${encodeURIComponent(groupId)}/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}?$select=id,from,body,createdDateTime`;
|
|
44
|
-
try {
|
|
45
|
-
return await require_resolve_allowlist.fetchGraphJson({
|
|
46
|
-
token,
|
|
47
|
-
path,
|
|
48
|
-
...deadline ? { deadline } : {}
|
|
49
|
-
});
|
|
50
|
-
} catch {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Fetch a single chat message's full text via Graph and return plain text.
|
|
56
|
-
*
|
|
57
|
-
* Used to recover the complete quoted message for Teams quote replies: the
|
|
58
|
-
* inbound blockquote only carries a Teams-truncated `preview` snippet. The
|
|
59
|
-
* app-only `GET /chats/{chatId}/messages/{messageId}` endpoint IS permitted
|
|
60
|
-
* with the `Chat.Read.All` application permission.
|
|
61
|
-
*
|
|
62
|
-
* Returns undefined on any failure so callers degrade to the truncated preview.
|
|
63
|
-
*/
|
|
64
|
-
async function fetchChatMessageText(token, chatId, messageId, deadline) {
|
|
65
|
-
const path = `/chats/${encodeURIComponent(chatId)}/messages/${encodeURIComponent(messageId)}`;
|
|
66
|
-
try {
|
|
67
|
-
const msg = await require_resolve_allowlist.fetchGraphJson({
|
|
68
|
-
token,
|
|
69
|
-
path,
|
|
70
|
-
...deadline ? { deadline } : {}
|
|
71
|
-
});
|
|
72
|
-
const raw = msg.body?.content ?? "";
|
|
73
|
-
return (msg.body?.contentType === "html" ? stripHtmlFromTeamsMessage(raw) : raw.trim()) || void 0;
|
|
74
|
-
} catch {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Fetch thread replies for a channel message, ordered chronologically.
|
|
80
|
-
*
|
|
81
|
-
* **Limitation:** The Graph API replies endpoint (`/messages/{id}/replies`) does not
|
|
82
|
-
* support `$orderby`, so results are always returned in ascending (oldest-first) order.
|
|
83
|
-
* Combined with the `$top` cap of 50, this means only the **oldest 50 replies** are
|
|
84
|
-
* returned for long threads — newer replies are silently omitted. There is currently no
|
|
85
|
-
* Graph API workaround for this; pagination via `@odata.nextLink` can retrieve more
|
|
86
|
-
* replies but still in ascending order only.
|
|
87
|
-
*/
|
|
88
|
-
async function fetchThreadReplies(token, groupId, channelId, messageId, limit = 50, deadline) {
|
|
89
|
-
return (await require_resolve_allowlist.fetchGraphJson({
|
|
90
|
-
token,
|
|
91
|
-
path: `/teams/${encodeURIComponent(groupId)}/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}/replies?$top=${Math.min(Math.max(limit, 1), 50)}&$select=id,from,body,createdDateTime`,
|
|
92
|
-
...deadline ? { deadline } : {}
|
|
93
|
-
})).value ?? [];
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Format thread messages into a context string for the agent.
|
|
97
|
-
* Skips the current message (by id) and blank messages.
|
|
98
|
-
*/
|
|
99
|
-
function formatThreadContext(messages, currentMessageId) {
|
|
100
|
-
const lines = [];
|
|
101
|
-
for (const msg of messages) {
|
|
102
|
-
if (msg.id && msg.id === currentMessageId) continue;
|
|
103
|
-
const sender = msg.from?.user?.displayName ?? msg.from?.application?.displayName ?? "unknown";
|
|
104
|
-
const contentType = msg.body?.contentType ?? "text";
|
|
105
|
-
const rawContent = msg.body?.content ?? "";
|
|
106
|
-
const content = contentType === "html" ? stripHtmlFromTeamsMessage(rawContent) : rawContent.trim();
|
|
107
|
-
if (!content) continue;
|
|
108
|
-
lines.push(`${sender}: ${content}`);
|
|
109
|
-
}
|
|
110
|
-
return lines.join("\n");
|
|
111
|
-
}
|
|
112
|
-
//#endregion
|
|
113
|
-
//#region extensions/msteams/src/reaction-types.ts
|
|
114
|
-
const TEAMS_REACTION_EMOJI = {
|
|
115
|
-
like: "👍",
|
|
116
|
-
heart: "❤️",
|
|
117
|
-
laugh: "😆",
|
|
118
|
-
surprised: "😮",
|
|
119
|
-
sad: "😢",
|
|
120
|
-
angry: "😡"
|
|
121
|
-
};
|
|
122
|
-
const TEAMS_REACTION_TYPES = Object.keys(TEAMS_REACTION_EMOJI);
|
|
123
|
-
function getMSTeamsReactionEmoji(raw) {
|
|
124
|
-
return TEAMS_REACTION_EMOJI[raw.trim().toLowerCase()];
|
|
125
|
-
}
|
|
126
|
-
function resolveMSTeamsReactionEmoji(raw) {
|
|
127
|
-
const normalized = raw.trim();
|
|
128
|
-
if (!normalized) throw new Error(`Reaction type is required. Common types: ${TEAMS_REACTION_TYPES.join(", ")}`);
|
|
129
|
-
return getMSTeamsReactionEmoji(normalized) ?? normalized;
|
|
130
|
-
}
|
|
131
|
-
//#endregion
|
|
132
26
|
//#region extensions/msteams/src/file-consent.ts
|
|
133
27
|
/**
|
|
134
28
|
* FileConsentCard utilities for MS Teams large file uploads (>4MB) in personal chats.
|
|
@@ -267,12 +161,12 @@ async function uploadToConsentUrl(params) {
|
|
|
267
161
|
//#endregion
|
|
268
162
|
//#region extensions/msteams/src/pending-uploads-fs.ts
|
|
269
163
|
/** TTL for persisted pending uploads (matches in-memory store). */
|
|
270
|
-
const PENDING_UPLOAD_TTL_MS$1 =
|
|
164
|
+
const PENDING_UPLOAD_TTL_MS$1 = 3e5;
|
|
271
165
|
/** Cap to avoid unbounded growth if a process crashes mid-flow. */
|
|
272
166
|
const MAX_PENDING_UPLOADS = 100;
|
|
273
167
|
const MAX_CHUNKS_PER_UPLOAD = 3072;
|
|
274
168
|
const MAX_PENDING_UPLOAD_CHUNK_ROWS = 45e3;
|
|
275
|
-
const RAW_CHUNK_BYTES =
|
|
169
|
+
const RAW_CHUNK_BYTES = 36864;
|
|
276
170
|
const PENDING_UPLOAD_META_MAX_ENTRIES = 200;
|
|
277
171
|
const PENDING_UPLOAD_META_NAMESPACE = "pending-uploads";
|
|
278
172
|
const PENDING_UPLOAD_CHUNKS_NAMESPACE = "pending-upload-chunks";
|
|
@@ -463,7 +357,7 @@ const { pendingUploads, pendingUploadTimers } = (0, openclaw_plugin_sdk_global_s
|
|
|
463
357
|
state.pendingUploads.clear();
|
|
464
358
|
});
|
|
465
359
|
/** TTL for pending uploads: 5 minutes */
|
|
466
|
-
const PENDING_UPLOAD_TTL_MS =
|
|
360
|
+
const PENDING_UPLOAD_TTL_MS = 3e5;
|
|
467
361
|
/**
|
|
468
362
|
* Store a file pending user consent.
|
|
469
363
|
* Returns the upload ID to include in the FileConsentCard context.
|
|
@@ -993,14 +887,16 @@ function formatMSTeamsMarkdown(markdown, tableMode) {
|
|
|
993
887
|
const mentions = [];
|
|
994
888
|
const entities = [];
|
|
995
889
|
const tokenPrefix = createTokenPrefix(markdown, "msteamsformat");
|
|
996
|
-
const
|
|
890
|
+
const mentionsProtected = protectMSTeamsMentions(protectMarkdownImages(markdown.replace(MARKDOWN_ENTITY_RE, (entity) => {
|
|
997
891
|
const index = entities.push(entity) - 1;
|
|
998
892
|
return `${tokenPrefix}h${index}${TOKEN_END}`;
|
|
999
|
-
}), tokenPrefix, images), tokenPrefix, mentions)
|
|
1000
|
-
|
|
893
|
+
}), tokenPrefix, images), tokenPrefix, mentions);
|
|
894
|
+
const tableInput = (0, openclaw_plugin_sdk_text_chunking.convertMarkdownTables)(mentionsProtected, tableMode);
|
|
895
|
+
const protectedMarkdown = (tableMode === "off" ? protectRawTablesOutsideFences(tableInput, tokenPrefix, rawTables) : tableInput).replace(ESCAPED_MARKDOWN_RE, (escaped) => {
|
|
1001
896
|
const index = escapedMarkdown.push(escaped) - 1;
|
|
1002
897
|
return `${tokenPrefix}e${index}${TOKEN_END}`;
|
|
1003
|
-
})
|
|
898
|
+
});
|
|
899
|
+
const ir = prefixMSTeamsBlockquotes(protectMSTeamsCode((0, openclaw_plugin_sdk_text_chunking.markdownToIR)(protectedMarkdown, {
|
|
1004
900
|
autolink: false,
|
|
1005
901
|
enableSpoilers: true,
|
|
1006
902
|
enableTaskLists: true,
|
|
@@ -1028,7 +924,8 @@ function formatMSTeamsMarkdown(markdown, tableMode) {
|
|
|
1028
924
|
prefix: `${tokenPrefix}h`,
|
|
1029
925
|
values: entities
|
|
1030
926
|
}
|
|
1031
|
-
]))
|
|
927
|
+
]));
|
|
928
|
+
let restored = restoreTokens((0, openclaw_plugin_sdk_text_chunking.renderMarkdownWithMarkers)(ir, {
|
|
1032
929
|
styleMarkers: MSTEAMS_MARKERS,
|
|
1033
930
|
escapeText: (text) => text,
|
|
1034
931
|
buildLink: (link) => ({
|
|
@@ -1174,7 +1071,10 @@ async function getChatMembers(params) {
|
|
|
1174
1071
|
},
|
|
1175
1072
|
signal
|
|
1176
1073
|
});
|
|
1177
|
-
if (!res.ok)
|
|
1074
|
+
if (!res.ok) {
|
|
1075
|
+
const message = res.status === 403 ? "Get chat members failed; verify Graph chat-member permissions and tenant access policies" : "Get chat members failed";
|
|
1076
|
+
throw await require_resolve_allowlist.createMSTeamsHttpError(res, message);
|
|
1077
|
+
}
|
|
1178
1078
|
return ((await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(res, "msteams.graph-upload.getChatMembers")).value ?? []).map((member) => ({ aadObjectId: member.userId ?? "" })).filter((member) => member.aadObjectId);
|
|
1179
1079
|
}
|
|
1180
1080
|
});
|
|
@@ -1394,10 +1294,9 @@ async function withRevokedProxyFallback(params) {
|
|
|
1394
1294
|
}
|
|
1395
1295
|
//#endregion
|
|
1396
1296
|
//#region extensions/msteams/src/sdk-proactive.ts
|
|
1397
|
-
const
|
|
1398
|
-
const loadMSTeamsQuoteModule = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeModule)(() => import("@microsoft/teams.api/dist/activities/message/message.js").then((message) => ({ MessageActivityInput: message.MessageActivityInput })));
|
|
1297
|
+
const loadMSTeamsApiModule = (0, openclaw_plugin_sdk_lazy_runtime.createLazyRuntimeModule)(() => import("@microsoft/teams.api"));
|
|
1399
1298
|
async function quoteMSTeamsActivity(activity, messageId) {
|
|
1400
|
-
const { MessageActivityInput } = await
|
|
1299
|
+
const { MessageActivityInput } = await loadMSTeamsApiModule();
|
|
1401
1300
|
if (typeof activity === "string") return new MessageActivityInput(activity).prependQuote(messageId);
|
|
1402
1301
|
if (activity.type !== "message") return activity;
|
|
1403
1302
|
return MessageActivityInput.from(activity).prependQuote(messageId);
|
|
@@ -1466,7 +1365,7 @@ async function getApiClientForReference(app, ref) {
|
|
|
1466
1365
|
const appInternals = app;
|
|
1467
1366
|
const httpClient = appInternals.api?.http ?? appInternals.client;
|
|
1468
1367
|
if (!httpClient) return api;
|
|
1469
|
-
const { Client } = await
|
|
1368
|
+
const { Client } = await loadMSTeamsApiModule();
|
|
1470
1369
|
return new Client(ref.serviceUrl, httpClient);
|
|
1471
1370
|
}
|
|
1472
1371
|
function mergeReferenceIntoActivity(activity, ref) {
|
|
@@ -1530,12 +1429,12 @@ async function deleteMSTeamsActivityWithReference(app, source, activityId, optio
|
|
|
1530
1429
|
* MSTeams-specific media size limit (100MB).
|
|
1531
1430
|
* Higher than the default to support Teams file-consent and SharePoint uploads.
|
|
1532
1431
|
*/
|
|
1533
|
-
const MSTEAMS_MAX_MEDIA_BYTES =
|
|
1432
|
+
const MSTEAMS_MAX_MEDIA_BYTES = 104857600;
|
|
1534
1433
|
/**
|
|
1535
1434
|
* Threshold for large files that require FileConsentCard flow in personal chats.
|
|
1536
1435
|
* Files >= 4MB use consent flow; smaller images can use inline base64.
|
|
1537
1436
|
*/
|
|
1538
|
-
const FILE_CONSENT_THRESHOLD_BYTES =
|
|
1437
|
+
const FILE_CONSENT_THRESHOLD_BYTES = 4194304;
|
|
1539
1438
|
function normalizeConversationId(rawId) {
|
|
1540
1439
|
return rawId.split(";")[0] ?? rawId;
|
|
1541
1440
|
}
|
|
@@ -1747,13 +1646,14 @@ async function sendMSTeamsMessages(params) {
|
|
|
1747
1646
|
};
|
|
1748
1647
|
let providerDispatchStarted = false;
|
|
1749
1648
|
const sendMessageInContext = async (sendFn, message, messageIndex) => {
|
|
1649
|
+
let activity;
|
|
1750
1650
|
let pendingUploadId;
|
|
1751
1651
|
let response;
|
|
1752
1652
|
try {
|
|
1753
1653
|
response = await sendWithRetry(async () => {
|
|
1754
|
-
|
|
1755
|
-
pendingUploadId
|
|
1756
|
-
|
|
1654
|
+
activity ??= await buildActivity(message, params.conversationRef, params.tokenProvider, params.sharePointSiteId, params.mediaMaxBytes, { feedbackLoopEnabled: params.feedbackLoopEnabled });
|
|
1655
|
+
pendingUploadId ??= typeof activity["_pendingUploadId"] === "string" ? activity["_pendingUploadId"] : void 0;
|
|
1656
|
+
delete activity["_pendingUploadId"];
|
|
1757
1657
|
providerDispatchStarted = true;
|
|
1758
1658
|
return await sendFn(activity);
|
|
1759
1659
|
}, {
|
|
@@ -1852,48 +1752,18 @@ Object.defineProperty(exports, "extractMessageId", {
|
|
|
1852
1752
|
return extractMessageId;
|
|
1853
1753
|
}
|
|
1854
1754
|
});
|
|
1855
|
-
Object.defineProperty(exports, "fetchChannelMessage", {
|
|
1856
|
-
enumerable: true,
|
|
1857
|
-
get: function() {
|
|
1858
|
-
return fetchChannelMessage;
|
|
1859
|
-
}
|
|
1860
|
-
});
|
|
1861
|
-
Object.defineProperty(exports, "fetchChatMessageText", {
|
|
1862
|
-
enumerable: true,
|
|
1863
|
-
get: function() {
|
|
1864
|
-
return fetchChatMessageText;
|
|
1865
|
-
}
|
|
1866
|
-
});
|
|
1867
|
-
Object.defineProperty(exports, "fetchThreadReplies", {
|
|
1868
|
-
enumerable: true,
|
|
1869
|
-
get: function() {
|
|
1870
|
-
return fetchThreadReplies;
|
|
1871
|
-
}
|
|
1872
|
-
});
|
|
1873
1755
|
Object.defineProperty(exports, "formatMSTeamsMarkdown", {
|
|
1874
1756
|
enumerable: true,
|
|
1875
1757
|
get: function() {
|
|
1876
1758
|
return formatMSTeamsMarkdown;
|
|
1877
1759
|
}
|
|
1878
1760
|
});
|
|
1879
|
-
Object.defineProperty(exports, "formatThreadContext", {
|
|
1880
|
-
enumerable: true,
|
|
1881
|
-
get: function() {
|
|
1882
|
-
return formatThreadContext;
|
|
1883
|
-
}
|
|
1884
|
-
});
|
|
1885
1761
|
Object.defineProperty(exports, "getDriveItemProperties", {
|
|
1886
1762
|
enumerable: true,
|
|
1887
1763
|
get: function() {
|
|
1888
1764
|
return getDriveItemProperties;
|
|
1889
1765
|
}
|
|
1890
1766
|
});
|
|
1891
|
-
Object.defineProperty(exports, "getMSTeamsReactionEmoji", {
|
|
1892
|
-
enumerable: true,
|
|
1893
|
-
get: function() {
|
|
1894
|
-
return getMSTeamsReactionEmoji;
|
|
1895
|
-
}
|
|
1896
|
-
});
|
|
1897
1767
|
Object.defineProperty(exports, "getPendingUpload", {
|
|
1898
1768
|
enumerable: true,
|
|
1899
1769
|
get: function() {
|
|
@@ -1948,12 +1818,6 @@ Object.defineProperty(exports, "requiresFileConsent", {
|
|
|
1948
1818
|
return requiresFileConsent;
|
|
1949
1819
|
}
|
|
1950
1820
|
});
|
|
1951
|
-
Object.defineProperty(exports, "resolveMSTeamsReactionEmoji", {
|
|
1952
|
-
enumerable: true,
|
|
1953
|
-
get: function() {
|
|
1954
|
-
return resolveMSTeamsReactionEmoji;
|
|
1955
|
-
}
|
|
1956
|
-
});
|
|
1957
1821
|
Object.defineProperty(exports, "sendMSTeamsActivityWithReference", {
|
|
1958
1822
|
enumerable: true,
|
|
1959
1823
|
get: function() {
|
|
@@ -1978,12 +1842,6 @@ Object.defineProperty(exports, "setPendingUploadActivityIdFs", {
|
|
|
1978
1842
|
return setPendingUploadActivityIdFs;
|
|
1979
1843
|
}
|
|
1980
1844
|
});
|
|
1981
|
-
Object.defineProperty(exports, "stripHtmlFromTeamsMessage", {
|
|
1982
|
-
enumerable: true,
|
|
1983
|
-
get: function() {
|
|
1984
|
-
return stripHtmlFromTeamsMessage;
|
|
1985
|
-
}
|
|
1986
|
-
});
|
|
1987
1845
|
Object.defineProperty(exports, "updateMSTeamsActivityWithReference", {
|
|
1988
1846
|
enumerable: true,
|
|
1989
1847
|
get: function() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
1
|
+
const require_resolve_allowlist = require("./resolve-allowlist-BrdWKHE-.cjs");
|
|
2
2
|
let openclaw_plugin_sdk_runtime_env = require("openclaw/plugin-sdk/runtime-env");
|
|
3
3
|
let openclaw_plugin_sdk_provider_auth = require("openclaw/plugin-sdk/provider-auth");
|
|
4
4
|
let openclaw_plugin_sdk_provider_auth_runtime = require("openclaw/plugin-sdk/provider-auth-runtime");
|
|
@@ -52,7 +52,7 @@ async function loginMSTeamsDelegated(ctx, params) {
|
|
|
52
52
|
try {
|
|
53
53
|
const { code } = await (0, openclaw_plugin_sdk_provider_auth_runtime.waitForLocalOAuthCallback)({
|
|
54
54
|
expectedState: state,
|
|
55
|
-
timeoutMs:
|
|
55
|
+
timeoutMs: 3e5,
|
|
56
56
|
port: require_resolve_allowlist.MSTEAMS_OAUTH_CALLBACK_PORT,
|
|
57
57
|
callbackPath: require_resolve_allowlist.MSTEAMS_OAUTH_CALLBACK_PATH,
|
|
58
58
|
redirectUri: require_resolve_allowlist.MSTEAMS_OAUTH_REDIRECT_URI,
|
|
@@ -81,7 +81,8 @@ async function manualFlow(ctx, authUrl, state, verifier, params, cause) {
|
|
|
81
81
|
ctx.progress.update("OAuth URL ready");
|
|
82
82
|
ctx.log(`\nOpen this URL in your LOCAL browser:\n\n${authUrl}\n`);
|
|
83
83
|
ctx.progress.update("Waiting for you to paste the callback URL...");
|
|
84
|
-
const
|
|
84
|
+
const callbackInput = await ctx.prompt("Paste the redirect URL here: ");
|
|
85
|
+
const parsed = (0, openclaw_plugin_sdk_provider_auth_runtime.parseOAuthCallbackInput)(callbackInput, {
|
|
85
86
|
missingState: "Missing 'state' parameter in URL. Paste the full redirect URL.",
|
|
86
87
|
invalidInput: "Paste the full redirect URL (including code and state parameters), not just the authorization code."
|
|
87
88
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_rolldown_runtime = require("./rolldown-runtime-
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
|
|
2
2
|
const require_runtime = require("./runtime-gZTAuFux.cjs");
|
|
3
3
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
4
4
|
let openclaw_plugin_sdk_file_lock = require("openclaw/plugin-sdk/file-lock");
|
|
@@ -96,7 +96,7 @@ const MSTEAMS_CONVERSATIONS_LEGACY_FILENAME = "msteams-conversations.json";
|
|
|
96
96
|
const MSTEAMS_CONVERSATIONS_NAMESPACE = "conversations";
|
|
97
97
|
const MSTEAMS_MAX_CONVERSATIONS = 1e3;
|
|
98
98
|
const MSTEAMS_SQLITE_MAX_CONVERSATION_ROWS = 2e3;
|
|
99
|
-
const MSTEAMS_CONVERSATION_TTL_MS =
|
|
99
|
+
const MSTEAMS_CONVERSATION_TTL_MS = 31536e6;
|
|
100
100
|
const CONVERSATION_MUTATION_KEY = "conversations";
|
|
101
101
|
function createConversationStateStore(params) {
|
|
102
102
|
return require_runtime.getMSTeamsRuntime().state.openKeyedStore({
|
|
@@ -226,7 +226,7 @@ const MSTEAMS_MAX_POLLS = 1e3;
|
|
|
226
226
|
const MSTEAMS_SQLITE_MAX_POLL_ROWS = 2e3;
|
|
227
227
|
const MSTEAMS_POLL_VOTE_BUCKET_COUNT = 32;
|
|
228
228
|
const MSTEAMS_MAX_POLL_VOTE_BUCKET_ROWS = 1001 * MSTEAMS_POLL_VOTE_BUCKET_COUNT;
|
|
229
|
-
const MSTEAMS_POLL_TTL_MS =
|
|
229
|
+
const MSTEAMS_POLL_TTL_MS = 2592e6;
|
|
230
230
|
const POLL_MUTATION_KEY = "polls";
|
|
231
231
|
function normalizeChoiceValue(value) {
|
|
232
232
|
if (typeof value === "string") {
|
|
@@ -379,7 +379,8 @@ function selectRetainedMSTeamsPolls(polls) {
|
|
|
379
379
|
}
|
|
380
380
|
function normalizeMSTeamsPollSelections(poll, selections) {
|
|
381
381
|
const maxSelections = Math.max(1, poll.maxSelections);
|
|
382
|
-
|
|
382
|
+
const mapped = selections.map((entry) => (0, openclaw_plugin_sdk_number_runtime.parseStrictNonNegativeInteger)(entry)).filter((value) => value !== void 0).filter((value) => value >= 0 && value < poll.options.length).map((value) => String(value));
|
|
383
|
+
return (0, openclaw_plugin_sdk_string_coerce_runtime.uniqueStrings)(mapped).slice(0, maxSelections);
|
|
383
384
|
}
|
|
384
385
|
function splitMSTeamsPoll(poll) {
|
|
385
386
|
const { votes, ...metadata } = poll;
|
package/dist/qa-runner-api.cjs
CHANGED
|
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
let openclaw_plugin_sdk_qa_runner_runtime = require("openclaw/plugin-sdk/qa-runner-runtime");
|
|
3
3
|
//#region extensions/msteams/src/qa/cli.ts
|
|
4
4
|
const DEFAULT_MSTEAMS_QA_SCENARIOS = ["channel-canary"];
|
|
5
|
-
const loadMSTeamsQaAdapterRuntime = (0, openclaw_plugin_sdk_qa_runner_runtime.createLazyCliRuntimeLoader)(() => Promise.resolve().then(() => require("./adapter.runtime-
|
|
5
|
+
const loadMSTeamsQaAdapterRuntime = (0, openclaw_plugin_sdk_qa_runner_runtime.createLazyCliRuntimeLoader)(() => Promise.resolve().then(() => require("./adapter.runtime-DDuc7sKJ.cjs")));
|
|
6
6
|
async function runQaMSTeams(options) {
|
|
7
7
|
await (0, openclaw_plugin_sdk_qa_runner_runtime.runLiveTransportQaSuiteCommand)({
|
|
8
8
|
channelId: "msteams",
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
const require_resolve_allowlist = require("./resolve-allowlist-BrdWKHE-.cjs");
|
|
2
|
+
let openclaw_plugin_sdk_html_entity_runtime = require("openclaw/plugin-sdk/html-entity-runtime");
|
|
3
|
+
//#region extensions/msteams/src/graph-thread.ts
|
|
4
|
+
/**
|
|
5
|
+
* Strip HTML tags from Teams message content, preserving @mention display names.
|
|
6
|
+
* Teams wraps mentions in <at>Name</at> tags.
|
|
7
|
+
*/
|
|
8
|
+
function stripHtmlFromTeamsMessage(html) {
|
|
9
|
+
let text = html.replace(/<at[^>]*>(.*?)<\/at>/gi, "@$1");
|
|
10
|
+
text = text.replace(/<[^>]*>/g, " ");
|
|
11
|
+
text = (0, openclaw_plugin_sdk_html_entity_runtime.decodeHtmlEntities)(text).replaceAll("\xA0", " ");
|
|
12
|
+
return text.replace(/\s+/g, " ").trim();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Fetch a single channel message (the parent/root of a thread).
|
|
16
|
+
* Returns undefined on error so callers can degrade gracefully.
|
|
17
|
+
*/
|
|
18
|
+
async function fetchChannelMessage(token, groupId, channelId, messageId, deadline) {
|
|
19
|
+
const path = `/teams/${encodeURIComponent(groupId)}/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}`;
|
|
20
|
+
try {
|
|
21
|
+
return await require_resolve_allowlist.fetchGraphJson({
|
|
22
|
+
token,
|
|
23
|
+
path,
|
|
24
|
+
...deadline ? { deadline } : {}
|
|
25
|
+
});
|
|
26
|
+
} catch {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Fetch a single chat message's full text via Graph and return plain text.
|
|
32
|
+
*
|
|
33
|
+
* Used to recover the complete quoted message for Teams quote replies: the
|
|
34
|
+
* inbound blockquote only carries a Teams-truncated `preview` snippet. The
|
|
35
|
+
* app-only `GET /chats/{chatId}/messages/{messageId}` endpoint IS permitted
|
|
36
|
+
* with the `Chat.Read.All` application permission.
|
|
37
|
+
*
|
|
38
|
+
* Returns undefined on any failure so callers degrade to the truncated preview.
|
|
39
|
+
*/
|
|
40
|
+
async function fetchChatMessageText(token, chatId, messageId, deadline) {
|
|
41
|
+
const path = `/chats/${encodeURIComponent(chatId)}/messages/${encodeURIComponent(messageId)}`;
|
|
42
|
+
try {
|
|
43
|
+
const msg = await require_resolve_allowlist.fetchGraphJson({
|
|
44
|
+
token,
|
|
45
|
+
path,
|
|
46
|
+
...deadline ? { deadline } : {}
|
|
47
|
+
});
|
|
48
|
+
const raw = msg.body?.content ?? "";
|
|
49
|
+
return (msg.body?.contentType === "html" ? stripHtmlFromTeamsMessage(raw) : raw.trim()) || void 0;
|
|
50
|
+
} catch {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Fetch thread replies for a channel message, ordered chronologically.
|
|
56
|
+
*
|
|
57
|
+
* **Limitation:** The Graph API replies endpoint (`/messages/{id}/replies`) does not
|
|
58
|
+
* support `$orderby`, so results are always returned in ascending (oldest-first) order.
|
|
59
|
+
* Combined with the `$top` cap of 50, this means only the **oldest 50 replies** are
|
|
60
|
+
* returned for long threads — newer replies are silently omitted. There is currently no
|
|
61
|
+
* Graph API workaround for this; pagination via `@odata.nextLink` can retrieve more
|
|
62
|
+
* replies but still in ascending order only.
|
|
63
|
+
*/
|
|
64
|
+
async function fetchThreadReplies(token, groupId, channelId, messageId, limit = 50, deadline) {
|
|
65
|
+
const path = `/teams/${encodeURIComponent(groupId)}/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}/replies?$top=${Math.min(Math.max(limit, 1), 50)}`;
|
|
66
|
+
return (await require_resolve_allowlist.fetchGraphJson({
|
|
67
|
+
token,
|
|
68
|
+
path,
|
|
69
|
+
...deadline ? { deadline } : {}
|
|
70
|
+
})).value ?? [];
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Format thread messages into a context string for the agent.
|
|
74
|
+
* Skips the current message (by id) and blank messages.
|
|
75
|
+
*/
|
|
76
|
+
function formatThreadContext(messages, currentMessageId) {
|
|
77
|
+
const lines = [];
|
|
78
|
+
for (const msg of messages) {
|
|
79
|
+
if (msg.id && msg.id === currentMessageId) continue;
|
|
80
|
+
const sender = msg.from?.user?.displayName ?? msg.from?.application?.displayName ?? "unknown";
|
|
81
|
+
const contentType = msg.body?.contentType ?? "text";
|
|
82
|
+
const rawContent = msg.body?.content ?? "";
|
|
83
|
+
const content = contentType === "html" ? stripHtmlFromTeamsMessage(rawContent) : rawContent.trim();
|
|
84
|
+
if (!content) continue;
|
|
85
|
+
lines.push(`${sender}: ${content}`);
|
|
86
|
+
}
|
|
87
|
+
return lines.join("\n");
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region extensions/msteams/src/reaction-types.ts
|
|
91
|
+
const TEAMS_REACTION_EMOJI = {
|
|
92
|
+
like: "👍",
|
|
93
|
+
heart: "❤️",
|
|
94
|
+
laugh: "😆",
|
|
95
|
+
surprised: "😮",
|
|
96
|
+
sad: "😢",
|
|
97
|
+
angry: "😡"
|
|
98
|
+
};
|
|
99
|
+
const TEAMS_REACTION_TYPES = Object.keys(TEAMS_REACTION_EMOJI);
|
|
100
|
+
function getMSTeamsReactionEmoji(raw) {
|
|
101
|
+
return TEAMS_REACTION_EMOJI[raw.trim().toLowerCase()];
|
|
102
|
+
}
|
|
103
|
+
function resolveMSTeamsReactionEmoji(raw) {
|
|
104
|
+
const normalized = raw.trim();
|
|
105
|
+
if (!normalized) throw new Error(`Reaction type is required. Common types: ${TEAMS_REACTION_TYPES.join(", ")}`);
|
|
106
|
+
return getMSTeamsReactionEmoji(normalized) ?? normalized;
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
Object.defineProperty(exports, "fetchChannelMessage", {
|
|
110
|
+
enumerable: true,
|
|
111
|
+
get: function() {
|
|
112
|
+
return fetchChannelMessage;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
Object.defineProperty(exports, "fetchChatMessageText", {
|
|
116
|
+
enumerable: true,
|
|
117
|
+
get: function() {
|
|
118
|
+
return fetchChatMessageText;
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
Object.defineProperty(exports, "fetchThreadReplies", {
|
|
122
|
+
enumerable: true,
|
|
123
|
+
get: function() {
|
|
124
|
+
return fetchThreadReplies;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
Object.defineProperty(exports, "formatThreadContext", {
|
|
128
|
+
enumerable: true,
|
|
129
|
+
get: function() {
|
|
130
|
+
return formatThreadContext;
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
Object.defineProperty(exports, "getMSTeamsReactionEmoji", {
|
|
134
|
+
enumerable: true,
|
|
135
|
+
get: function() {
|
|
136
|
+
return getMSTeamsReactionEmoji;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
Object.defineProperty(exports, "resolveMSTeamsReactionEmoji", {
|
|
140
|
+
enumerable: true,
|
|
141
|
+
get: function() {
|
|
142
|
+
return resolveMSTeamsReactionEmoji;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
Object.defineProperty(exports, "stripHtmlFromTeamsMessage", {
|
|
146
|
+
enumerable: true,
|
|
147
|
+
get: function() {
|
|
148
|
+
return stripHtmlFromTeamsMessage;
|
|
149
|
+
}
|
|
150
|
+
});
|