@openclaw/msteams 2026.9.4 → 2026.9.6
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/assets/activity.svg +40 -0
- package/assets/icon.png +0 -0
- package/dist/{adapter.runtime-BzR3RK2J.cjs → .setup/adapter.runtime-CQWZeqB5.cjs} +5 -3
- package/dist/{approval-handler.runtime-DRhFNeJS.cjs → .setup/approval-handler.runtime-CUnanUdR.cjs} +3 -3
- package/dist/{channel-B9LIyYeu.cjs → .setup/channel-BDp16XRR.cjs} +128 -89
- package/dist/{channel.runtime-BergqMHg.cjs → .setup/channel.runtime-Cv5F8JCa.cjs} +61 -34
- package/dist/{channel.setup-BhxokviI.cjs → .setup/channel.setup-BVDfgdCc.cjs} +3 -3
- package/dist/{delegated-state-DiEz9JIa.cjs → .setup/delegated-state-u-ywZyZT.cjs} +5 -5
- package/dist/{messenger-TLdZf9Ar.cjs → .setup/messenger-8RA1FUJa.cjs} +112 -188
- package/dist/{oauth-DUtLTz2u.cjs → .setup/oauth-C6m7dvHj.cjs} +1 -1
- package/dist/{polls-BBdZPx_R.cjs → .setup/polls-BJ4-4uZm.cjs} +14 -7
- package/dist/{reaction-types-BbBBdnQ5.cjs → .setup/reaction-types-C7RA7Wxt.cjs} +1 -1
- package/dist/{resolve-allowlist-DmUTQxEz.cjs → .setup/resolve-allowlist-CHzaaWiC.cjs} +135 -93
- package/dist/.setup/secret-contract-api-ChQdBeU1.cjs +4 -0
- package/dist/.setup/secret-contract-api-ipiUsANg.cjs +28 -0
- package/dist/{send-CU61PSDN.cjs → .setup/send-CYN_N7O1.cjs} +99 -34
- package/dist/.setup/setup-plugin-api-DpiaA8z1.cjs +3 -0
- package/dist/{src-D7Do7sM5.cjs → .setup/src-BfOCwlHp.cjs} +150 -125
- package/dist/{sso-token-store-DTeYxubp.cjs → .setup/sso-token-store-YYLHXgFH.cjs} +1 -1
- package/dist/{thread-session-NmA7_njI.cjs → .setup/thread-session-CXgHK-yi.cjs} +1 -1
- package/dist/api.cjs +2 -2
- package/dist/channel-config-api.cjs +1 -1
- package/dist/channel-plugin-api.cjs +1 -1
- package/dist/configured-state.cjs +1 -1
- package/dist/directory-contract-api.cjs +1 -1
- package/dist/doctor-contract-api.cjs +64 -62
- package/dist/qa-runner-api.cjs +1 -1
- package/dist/runtime-api.cjs +1 -1
- package/dist/secret-contract-api.cjs +4 -13
- package/dist/setup-entry.cjs +5 -3
- package/dist/setup-plugin-api.cjs +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +14 -11
- /package/dist/{approval-card-CPNH_q3P.cjs → .setup/approval-card-CPNH_q3P.cjs} +0 -0
- /package/dist/{config-schema-D22Lr1Qk.cjs → .setup/config-schema-D22Lr1Qk.cjs} +0 -0
- /package/dist/{rolldown-runtime-VH7oDXx4.cjs → .setup/rolldown-runtime-VH7oDXx4.cjs} +0 -0
- /package/dist/{runtime-gZTAuFux.cjs → .setup/runtime-gZTAuFux.cjs} +0 -0
- /package/dist/{secret-input-C65t6kjM.cjs → .setup/secret-input-C65t6kjM.cjs} +0 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
|
|
2
2
|
const require_runtime = require("./runtime-gZTAuFux.cjs");
|
|
3
|
-
require("
|
|
4
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
5
|
-
const require_channel = require("./channel-
|
|
6
|
-
const require_thread_session = require("./thread-session-
|
|
7
|
-
const require_channel_setup = require("./channel.setup-
|
|
8
|
-
const require_polls = require("./polls-
|
|
9
|
-
const require_sso_token_store = require("./sso-token-store-
|
|
3
|
+
require("../runtime-api.cjs");
|
|
4
|
+
const require_resolve_allowlist = require("./resolve-allowlist-CHzaaWiC.cjs");
|
|
5
|
+
const require_channel = require("./channel-BDp16XRR.cjs");
|
|
6
|
+
const require_thread_session = require("./thread-session-CXgHK-yi.cjs");
|
|
7
|
+
const require_channel_setup = require("./channel.setup-BVDfgdCc.cjs");
|
|
8
|
+
const require_polls = require("./polls-BJ4-4uZm.cjs");
|
|
9
|
+
const require_sso_token_store = require("./sso-token-store-YYLHXgFH.cjs");
|
|
10
10
|
const require_approval_card = require("./approval-card-CPNH_q3P.cjs");
|
|
11
|
-
const require_messenger = require("./messenger-
|
|
12
|
-
const require_reaction_types = require("./reaction-types-
|
|
11
|
+
const require_messenger = require("./messenger-8RA1FUJa.cjs");
|
|
12
|
+
const require_reaction_types = require("./reaction-types-C7RA7Wxt.cjs");
|
|
13
13
|
let openclaw_plugin_sdk_channel_outbound = require("openclaw/plugin-sdk/channel-outbound");
|
|
14
14
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
15
15
|
let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
|
|
@@ -19,10 +19,10 @@ let openclaw_plugin_sdk_media_runtime = require("openclaw/plugin-sdk/media-runti
|
|
|
19
19
|
let openclaw_plugin_sdk_ssrf_runtime = require("openclaw/plugin-sdk/ssrf-runtime");
|
|
20
20
|
let openclaw_plugin_sdk_number_runtime = require("openclaw/plugin-sdk/number-runtime");
|
|
21
21
|
let openclaw_plugin_sdk_text_utility_runtime = require("openclaw/plugin-sdk/text-utility-runtime");
|
|
22
|
+
let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
|
|
22
23
|
let openclaw_plugin_sdk_routing = require("openclaw/plugin-sdk/routing");
|
|
23
24
|
let node_crypto = require("node:crypto");
|
|
24
25
|
node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
|
|
25
|
-
let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
|
|
26
26
|
let openclaw_plugin_sdk_channel_inbound = require("openclaw/plugin-sdk/channel-inbound");
|
|
27
27
|
let openclaw_plugin_sdk_approval_gateway_runtime = require("openclaw/plugin-sdk/approval-gateway-runtime");
|
|
28
28
|
let openclaw_plugin_sdk_channel_ingress_runtime = require("openclaw/plugin-sdk/channel-ingress-runtime");
|
|
@@ -47,18 +47,35 @@ const MAX_LEARNING_ENTRIES = 1e4;
|
|
|
47
47
|
function learningStoreKey(storePath, sessionKey) {
|
|
48
48
|
return node_crypto.default.createHash("sha256").update(`${storePath}\0${sessionKey}`, "utf8").digest("hex");
|
|
49
49
|
}
|
|
50
|
+
function appendFeedbackLearning(current, prepared) {
|
|
51
|
+
return {
|
|
52
|
+
sessionKey: prepared.sessionKey,
|
|
53
|
+
learnings: [...current?.learnings ?? [], prepared.learning].slice(-10),
|
|
54
|
+
updatedAt: prepared.updatedAt
|
|
55
|
+
};
|
|
56
|
+
}
|
|
50
57
|
async function storeSessionLearning(params) {
|
|
51
58
|
const store = require_runtime.getMSTeamsRuntime().state.openKeyedStore({
|
|
52
59
|
namespace: LEARNINGS_NAMESPACE,
|
|
53
60
|
maxEntries: MAX_LEARNING_ENTRIES
|
|
54
61
|
});
|
|
55
62
|
const key = learningStoreKey(params.storePath, params.sessionKey);
|
|
56
|
-
if (!store.
|
|
57
|
-
|
|
63
|
+
if (!store.observe || !store.compareAndApply) throw new Error("plugin state atomic comparison is unavailable");
|
|
64
|
+
const prepared = {
|
|
58
65
|
sessionKey: params.sessionKey,
|
|
59
|
-
|
|
66
|
+
learning: params.learning,
|
|
60
67
|
updatedAt: Date.now()
|
|
61
|
-
}
|
|
68
|
+
};
|
|
69
|
+
let observed = await store.observe(key);
|
|
70
|
+
while (true) {
|
|
71
|
+
const result = await store.compareAndApply(key, observed.comparison, {
|
|
72
|
+
operation: "update",
|
|
73
|
+
action: "set",
|
|
74
|
+
value: appendFeedbackLearning(observed.value, prepared)
|
|
75
|
+
});
|
|
76
|
+
if (result.status !== "conflict") return;
|
|
77
|
+
observed = result.current;
|
|
78
|
+
}
|
|
62
79
|
}
|
|
63
80
|
//#endregion
|
|
64
81
|
//#region extensions/msteams/src/feedback-reflection.ts
|
|
@@ -310,6 +327,7 @@ async function resolveMSTeamsSenderAccess(params) {
|
|
|
310
327
|
const conversationId = require_resolve_allowlist.normalizeMSTeamsConversationId(activity.conversation?.id ?? "unknown");
|
|
311
328
|
const convType = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(activity.conversation?.conversationType);
|
|
312
329
|
const isDirectMessage = convType === "personal" || !convType && !activity.conversation?.isGroup;
|
|
330
|
+
const hasConflictingConversationScope = isDirectMessage && (activity.conversation?.isGroup === true || activity.channelData?.team !== void 0 || activity.channelData?.channel !== void 0);
|
|
313
331
|
const senderId = activity.from?.aadObjectId ?? activity.from?.id ?? "unknown";
|
|
314
332
|
const senderName = activity.from?.name ?? activity.from?.id ?? senderId;
|
|
315
333
|
const core = require_runtime.getMSTeamsRuntime();
|
|
@@ -332,7 +350,7 @@ async function resolveMSTeamsSenderAccess(params) {
|
|
|
332
350
|
channelName: activity.channelData?.channel?.name,
|
|
333
351
|
allowNameMatching
|
|
334
352
|
});
|
|
335
|
-
const resolved = await
|
|
353
|
+
const resolved = await core.channel.inbound.ingress.resolveStable({
|
|
336
354
|
channelId: "msteams",
|
|
337
355
|
accountId: pairing.accountId,
|
|
338
356
|
identity: {
|
|
@@ -397,6 +415,7 @@ async function resolveMSTeamsSenderAccess(params) {
|
|
|
397
415
|
channelIngress: resolved,
|
|
398
416
|
pairing,
|
|
399
417
|
isDirectMessage,
|
|
418
|
+
hasConflictingConversationScope,
|
|
400
419
|
conversationId,
|
|
401
420
|
senderId,
|
|
402
421
|
senderName,
|
|
@@ -419,9 +438,14 @@ async function admitMSTeamsMessage(params) {
|
|
|
419
438
|
activity: params.activity,
|
|
420
439
|
hasControlCommand: isControlCommand
|
|
421
440
|
});
|
|
422
|
-
const { dmPolicy, senderId, senderName, pairing, isDirectMessage, channelGate, senderAccess, commandAccess, allowNameMatching, groupPolicy, msteamsCfg } = access;
|
|
441
|
+
const { dmPolicy, senderId, senderName, pairing, isDirectMessage, hasConflictingConversationScope, channelGate, senderAccess, commandAccess, allowNameMatching, groupPolicy, msteamsCfg } = access;
|
|
423
442
|
const effectiveDmAllowFrom = senderAccess.effectiveAllowFrom;
|
|
424
443
|
const effectiveGroupAllowFrom = senderAccess.effectiveGroupAllowFrom;
|
|
444
|
+
if (hasConflictingConversationScope) {
|
|
445
|
+
params.log.info("dropping message (conflicting conversation scope)", { conversationId: params.conversationId });
|
|
446
|
+
params.log.debug?.("dropping message (conflicting conversation scope)");
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
425
449
|
if (isDirectMessage && msteamsCfg && senderAccess.decision !== "allow") {
|
|
426
450
|
if (senderAccess.reasonCode === "dm_policy_disabled") {
|
|
427
451
|
params.log.info("dropping dm (dms disabled)", {
|
|
@@ -873,11 +897,11 @@ function createAdvertisedMediaFact(kind, sourceId) {
|
|
|
873
897
|
if (sourceId) media.sourceId = sourceId;
|
|
874
898
|
return media;
|
|
875
899
|
}
|
|
876
|
-
function resolveMSTeamsAdvertisedMedia(attachments
|
|
900
|
+
function resolveMSTeamsAdvertisedMedia(attachments) {
|
|
877
901
|
const list = Array.isArray(attachments) ? attachments : [];
|
|
878
902
|
if (list.length === 0) return [];
|
|
879
903
|
const fileAttachments = list.filter(require_resolve_allowlist.isAdvertisedFileAttachment);
|
|
880
|
-
const inlineMedia = require_resolve_allowlist.
|
|
904
|
+
const inlineMedia = require_resolve_allowlist.extractInlineImageReferences(list).map((candidate) => createAdvertisedMediaFact("image", candidate.sourceId));
|
|
881
905
|
const htmlAttachmentIds = resolveUnrepresentedHtmlAttachmentIds(list);
|
|
882
906
|
return [
|
|
883
907
|
...fileAttachments.map((attachment) => createAdvertisedMediaFact(require_resolve_allowlist.isLikelyImageAttachment(attachment) ? "image" : require_resolve_allowlist.resolveMSTeamsMediaKind({
|
|
@@ -995,6 +1019,44 @@ function scopeCandidatesForUrl(url) {
|
|
|
995
1019
|
return ["https://api.botframework.com", "https://graph.microsoft.com"];
|
|
996
1020
|
}
|
|
997
1021
|
}
|
|
1022
|
+
function canonicalizeInlineBase64Payload(value) {
|
|
1023
|
+
let cleaned = "";
|
|
1024
|
+
let padding = 0;
|
|
1025
|
+
let sawPadding = false;
|
|
1026
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
1027
|
+
const code = value.charCodeAt(index);
|
|
1028
|
+
if (code <= 32) continue;
|
|
1029
|
+
if (code === 61) {
|
|
1030
|
+
padding += 1;
|
|
1031
|
+
if (padding > 2) return;
|
|
1032
|
+
sawPadding = true;
|
|
1033
|
+
cleaned += "=";
|
|
1034
|
+
continue;
|
|
1035
|
+
}
|
|
1036
|
+
if (sawPadding || !(code >= 65 && code <= 90 || code >= 97 && code <= 122 || code >= 48 && code <= 57 || code === 43 || code === 47)) return;
|
|
1037
|
+
cleaned += value[index];
|
|
1038
|
+
}
|
|
1039
|
+
return cleaned && cleaned.length % 4 === 0 ? cleaned : void 0;
|
|
1040
|
+
}
|
|
1041
|
+
function decodeInlineDataImage(src, maxBytes, totalBytes) {
|
|
1042
|
+
const match = /^data:(image\/[a-z0-9.+-]+)?(;base64)?,(.*)$/i.exec(src);
|
|
1043
|
+
if (!match) return null;
|
|
1044
|
+
const contentType = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeLowercaseStringOrEmpty)(match[1] ?? "");
|
|
1045
|
+
if (!Boolean(match[2])) return null;
|
|
1046
|
+
const canonicalPayload = canonicalizeInlineBase64Payload(match[3] ?? "");
|
|
1047
|
+
if (!canonicalPayload) return null;
|
|
1048
|
+
const estimatedBytes = Buffer.byteLength(canonicalPayload, "base64");
|
|
1049
|
+
if (estimatedBytes <= 0 || typeof maxBytes === "number" && (estimatedBytes > maxBytes || totalBytes + estimatedBytes > maxBytes)) return null;
|
|
1050
|
+
try {
|
|
1051
|
+
return {
|
|
1052
|
+
data: Buffer.from(canonicalPayload, "base64"),
|
|
1053
|
+
contentType,
|
|
1054
|
+
estimatedBytes
|
|
1055
|
+
};
|
|
1056
|
+
} catch {
|
|
1057
|
+
return null;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
998
1060
|
async function resolveInlineDataImageMime(inline) {
|
|
999
1061
|
const detectedMime = await require_runtime.getMSTeamsRuntime().media.detectMime({
|
|
1000
1062
|
buffer: inline.data,
|
|
@@ -1070,15 +1132,12 @@ async function downloadMSTeamsAttachments(params) {
|
|
|
1070
1132
|
sourceId: attachment.id?.trim() || void 0
|
|
1071
1133
|
};
|
|
1072
1134
|
});
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
maxInlineTotalBytes: params.maxBytes
|
|
1076
|
-
}).map((candidate) => {
|
|
1135
|
+
const maxInlineBytes = params.maxBytes;
|
|
1136
|
+
candidates.push(...require_resolve_allowlist.extractInlineImageReferences(list).map((candidate) => {
|
|
1077
1137
|
if (candidate.kind === "data") return {
|
|
1078
1138
|
kind: "data",
|
|
1079
1139
|
mediaKind: "image",
|
|
1080
|
-
|
|
1081
|
-
contentType: candidate.contentType,
|
|
1140
|
+
src: candidate.src,
|
|
1082
1141
|
sourceId: candidate.sourceId
|
|
1083
1142
|
};
|
|
1084
1143
|
if (candidate.kind === "url") return {
|
|
@@ -1095,30 +1154,33 @@ async function downloadMSTeamsAttachments(params) {
|
|
|
1095
1154
|
sourceId: candidate.sourceId
|
|
1096
1155
|
};
|
|
1097
1156
|
}));
|
|
1098
|
-
const
|
|
1099
|
-
maxInlineBytes: params.maxBytes,
|
|
1100
|
-
maxInlineTotalBytes: params.maxBytes
|
|
1101
|
-
});
|
|
1102
|
-
for (const advertised of advertisedMedia.slice(candidates.length)) candidates.push({
|
|
1157
|
+
for (const sourceId of resolveUnrepresentedHtmlAttachmentIds(list)) candidates.push({
|
|
1103
1158
|
kind: "unavailable",
|
|
1104
|
-
mediaKind:
|
|
1105
|
-
sourceId
|
|
1159
|
+
mediaKind: "document",
|
|
1160
|
+
sourceId
|
|
1106
1161
|
});
|
|
1107
1162
|
if (candidates.length === 0) return [];
|
|
1108
1163
|
const out = [];
|
|
1164
|
+
let totalInlineBytes = 0;
|
|
1109
1165
|
for (const candidate of candidates) {
|
|
1110
1166
|
if (candidate.kind === "unavailable") {
|
|
1111
1167
|
out.push(withSourceId({ kind: candidate.mediaKind }, candidate.sourceId));
|
|
1112
1168
|
continue;
|
|
1113
1169
|
}
|
|
1114
1170
|
if (candidate.kind === "data") {
|
|
1171
|
+
const decoded = decodeInlineDataImage(candidate.src, maxInlineBytes, totalInlineBytes);
|
|
1172
|
+
if (!decoded) {
|
|
1173
|
+
out.push(withSourceId({ kind: candidate.mediaKind }, candidate.sourceId));
|
|
1174
|
+
continue;
|
|
1175
|
+
}
|
|
1176
|
+
totalInlineBytes += decoded.estimatedBytes;
|
|
1115
1177
|
try {
|
|
1116
|
-
const contentType = await resolveInlineDataImageMime(
|
|
1178
|
+
const contentType = await resolveInlineDataImageMime(decoded);
|
|
1117
1179
|
if (!contentType) {
|
|
1118
1180
|
out.push(withSourceId({ kind: candidate.mediaKind }, candidate.sourceId));
|
|
1119
1181
|
continue;
|
|
1120
1182
|
}
|
|
1121
|
-
const saved = await require_runtime.getMSTeamsRuntime().channel.media.saveMediaBuffer(
|
|
1183
|
+
const saved = await require_runtime.getMSTeamsRuntime().channel.media.saveMediaBuffer(decoded.data, contentType, "inbound", params.maxBytes);
|
|
1122
1184
|
out.push(withSourceId({
|
|
1123
1185
|
path: saved.path,
|
|
1124
1186
|
contentType: saved.contentType,
|
|
@@ -1834,6 +1896,8 @@ function createTeamsReplyStreamController(params) {
|
|
|
1834
1896
|
return payloads;
|
|
1835
1897
|
};
|
|
1836
1898
|
const progressDraft = (0, openclaw_plugin_sdk_channel_outbound.createChannelProgressDraftCompositor)({
|
|
1899
|
+
preparedItems: true,
|
|
1900
|
+
formatPlainText: (text) => text,
|
|
1837
1901
|
entry: params.msteamsConfig,
|
|
1838
1902
|
mode: streamMode,
|
|
1839
1903
|
active: Boolean(stream) && streamMode === "progress",
|
|
@@ -1891,13 +1955,8 @@ function createTeamsReplyStreamController(params) {
|
|
|
1891
1955
|
params.log?.warn?.(`msteams stream emit failed, falling back to block delivery: ${(0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err)}`);
|
|
1892
1956
|
}
|
|
1893
1957
|
},
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
await progressDraft.noteActivity();
|
|
1897
|
-
},
|
|
1898
|
-
async pushProgressLine(line, options) {
|
|
1899
|
-
await progressDraft.pushToolProgress(line, options);
|
|
1900
|
-
},
|
|
1958
|
+
pushItemEvent: progressDraft.pushItemEvent.bind(progressDraft),
|
|
1959
|
+
pushToolEvent: progressDraft.pushToolEvent,
|
|
1901
1960
|
async pushReasoningProgress(text, options) {
|
|
1902
1961
|
await progressDraft.pushReasoningProgress(text, options);
|
|
1903
1962
|
},
|
|
@@ -2429,38 +2488,14 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2429
2488
|
streamController.resetReasoningProgress();
|
|
2430
2489
|
return false;
|
|
2431
2490
|
},
|
|
2432
|
-
onToolStart:
|
|
2433
|
-
|
|
2434
|
-
const detailMode = typeof payload?.detailMode === "string" ? payload.detailMode : void 0;
|
|
2435
|
-
await streamController.pushProgressLine((0, openclaw_plugin_sdk_channel_outbound.buildChannelProgressDraftLineForEntry)(msteamsCfg, {
|
|
2436
|
-
event: "tool",
|
|
2437
|
-
...typeof payload?.itemId === "string" ? { itemId: payload.itemId } : {},
|
|
2438
|
-
...typeof payload?.toolCallId === "string" ? { toolCallId: payload.toolCallId } : {},
|
|
2439
|
-
...name ? { name } : {},
|
|
2440
|
-
...typeof payload?.phase === "string" ? { phase: payload.phase } : {},
|
|
2441
|
-
...payload?.args && typeof payload.args === "object" ? { args: payload.args } : {}
|
|
2442
|
-
}, detailMode === "explain" || detailMode === "raw" ? { detailMode } : void 0), name ? { toolName: name } : void 0);
|
|
2443
|
-
return false;
|
|
2444
|
-
},
|
|
2445
|
-
onItemEvent: async (payload) => {
|
|
2446
|
-
await streamController.pushProgressLine((0, openclaw_plugin_sdk_channel_outbound.buildChannelProgressDraftLineForEntry)(msteamsCfg, {
|
|
2447
|
-
event: "item",
|
|
2448
|
-
...typeof payload?.itemId === "string" ? { itemId: payload.itemId } : {},
|
|
2449
|
-
...typeof payload?.toolCallId === "string" ? { toolCallId: payload.toolCallId } : {},
|
|
2450
|
-
...typeof payload?.kind === "string" ? { itemKind: payload.kind } : {},
|
|
2451
|
-
...typeof payload?.title === "string" ? { title: payload.title } : {},
|
|
2452
|
-
...typeof payload?.name === "string" ? { name: payload.name } : {},
|
|
2453
|
-
...typeof payload?.phase === "string" ? { phase: payload.phase } : {},
|
|
2454
|
-
...typeof payload?.status === "string" ? { status: payload.status } : {},
|
|
2455
|
-
...typeof payload?.summary === "string" ? { summary: payload.summary } : {},
|
|
2456
|
-
...typeof payload?.progressText === "string" ? { progressText: payload.progressText } : {},
|
|
2457
|
-
...typeof payload?.meta === "string" ? { meta: payload.meta } : {}
|
|
2458
|
-
}));
|
|
2459
|
-
return false;
|
|
2460
|
-
},
|
|
2491
|
+
onToolStart: streamController.pushToolEvent,
|
|
2492
|
+
onItemEvent: streamController.pushItemEvent,
|
|
2461
2493
|
onPlanUpdate: async (payload) => {
|
|
2462
2494
|
if (payload?.phase !== "update") return false;
|
|
2463
|
-
await streamController.pushPlanProgress((0, openclaw_plugin_sdk_channel_outbound.normalizeAgentPlanSteps)(payload.steps), {
|
|
2495
|
+
await streamController.pushPlanProgress((0, openclaw_plugin_sdk_channel_outbound.normalizeAgentPlanSteps)(payload.steps), {
|
|
2496
|
+
explanation: typeof payload.explanation === "string" ? payload.explanation : void 0,
|
|
2497
|
+
explanationFormat: payload.explanationFormat === "plain" ? "plain" : void 0
|
|
2498
|
+
});
|
|
2464
2499
|
return false;
|
|
2465
2500
|
},
|
|
2466
2501
|
onApprovalEvent: async (payload) => {
|
|
@@ -2473,36 +2508,6 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2473
2508
|
...typeof payload?.message === "string" ? { message: payload.message } : {}
|
|
2474
2509
|
});
|
|
2475
2510
|
return false;
|
|
2476
|
-
},
|
|
2477
|
-
onCommandOutput: async (payload) => {
|
|
2478
|
-
if (payload?.phase !== "end") return false;
|
|
2479
|
-
await streamController.pushProgressLine((0, openclaw_plugin_sdk_channel_outbound.buildChannelProgressDraftLineForEntry)(msteamsCfg, {
|
|
2480
|
-
event: "command-output",
|
|
2481
|
-
...typeof payload?.itemId === "string" ? { itemId: payload.itemId } : {},
|
|
2482
|
-
...typeof payload?.toolCallId === "string" ? { toolCallId: payload.toolCallId } : {},
|
|
2483
|
-
phase: payload.phase,
|
|
2484
|
-
...typeof payload?.title === "string" ? { title: payload.title } : {},
|
|
2485
|
-
...typeof payload?.name === "string" ? { name: payload.name } : {},
|
|
2486
|
-
...typeof payload?.status === "string" ? { status: payload.status } : {},
|
|
2487
|
-
...typeof payload?.exitCode === "number" ? { exitCode: payload.exitCode } : {}
|
|
2488
|
-
}));
|
|
2489
|
-
return false;
|
|
2490
|
-
},
|
|
2491
|
-
onPatchSummary: async (payload) => {
|
|
2492
|
-
if (payload?.phase !== "end") return false;
|
|
2493
|
-
await streamController.pushProgressLine((0, openclaw_plugin_sdk_channel_outbound.buildChannelProgressDraftLine)({
|
|
2494
|
-
event: "patch",
|
|
2495
|
-
...typeof payload?.itemId === "string" ? { itemId: payload.itemId } : {},
|
|
2496
|
-
...typeof payload?.toolCallId === "string" ? { toolCallId: payload.toolCallId } : {},
|
|
2497
|
-
phase: payload.phase,
|
|
2498
|
-
...typeof payload?.title === "string" ? { title: payload.title } : {},
|
|
2499
|
-
...typeof payload?.name === "string" ? { name: payload.name } : {},
|
|
2500
|
-
...Array.isArray(payload?.added) && payload.added.every((s) => typeof s === "string") ? { added: payload.added } : {},
|
|
2501
|
-
...Array.isArray(payload?.modified) && payload.modified.every((s) => typeof s === "string") ? { modified: payload.modified } : {},
|
|
2502
|
-
...Array.isArray(payload?.deleted) && payload.deleted.every((s) => typeof s === "string") ? { deleted: payload.deleted } : {},
|
|
2503
|
-
...typeof payload?.summary === "string" ? { summary: payload.summary } : {}
|
|
2504
|
-
}));
|
|
2505
|
-
return false;
|
|
2506
2511
|
}
|
|
2507
2512
|
} : {};
|
|
2508
2513
|
return {
|
|
@@ -2512,6 +2517,8 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2512
2517
|
},
|
|
2513
2518
|
delivery,
|
|
2514
2519
|
replyOptions: {
|
|
2520
|
+
progressPreambleEnabled: shouldSuppressDefaultToolProgressMessages,
|
|
2521
|
+
commentaryProgressEnabled: shouldSuppressDefaultToolProgressMessages,
|
|
2515
2522
|
...streamController.hasStream() ? { onPartialReply: (payload) => {
|
|
2516
2523
|
streamController.onPartialReply(payload);
|
|
2517
2524
|
return false;
|
|
@@ -2574,7 +2581,7 @@ async function dispatchMSTeamsInboundTurn(params) {
|
|
|
2574
2581
|
body: agentBody
|
|
2575
2582
|
});
|
|
2576
2583
|
const isRoomish = !isDirectMessage;
|
|
2577
|
-
const historyKey = isRoomish ?
|
|
2584
|
+
const historyKey = isRoomish ? facts.historyKey : void 0;
|
|
2578
2585
|
if (isRoomish && historyKey) combinedBody = (0, openclaw_plugin_sdk_reply_history.createChannelHistoryWindow)({ historyMap: conversationHistories }).buildPendingContext({
|
|
2579
2586
|
historyKey,
|
|
2580
2587
|
limit: historyLimit,
|
|
@@ -2843,8 +2850,7 @@ function buildStoredConversationReference(params) {
|
|
|
2843
2850
|
...threadId ? { threadId } : {}
|
|
2844
2851
|
};
|
|
2845
2852
|
}
|
|
2846
|
-
function assembleMSTeamsInboundFacts(
|
|
2847
|
-
const { entry, mediaMaxBytes } = params;
|
|
2853
|
+
function assembleMSTeamsInboundFacts(entry) {
|
|
2848
2854
|
const activity = entry.context.activity;
|
|
2849
2855
|
const conversation = activity.conversation;
|
|
2850
2856
|
const rawConversationId = conversation?.id ?? "";
|
|
@@ -2854,10 +2860,7 @@ function assembleMSTeamsInboundFacts(params) {
|
|
|
2854
2860
|
const isChannel = conversationType === "channel";
|
|
2855
2861
|
const teamId = activity.channelData?.team?.id;
|
|
2856
2862
|
const threadId = isChannel ? conversationMessageId ?? activity.replyToId ?? void 0 : void 0;
|
|
2857
|
-
const advertisedMedia = resolveMSTeamsAdvertisedMedia(entry.attachments
|
|
2858
|
-
maxInlineBytes: mediaMaxBytes,
|
|
2859
|
-
maxInlineTotalBytes: mediaMaxBytes
|
|
2860
|
-
});
|
|
2863
|
+
const advertisedMedia = resolveMSTeamsAdvertisedMedia(entry.attachments);
|
|
2861
2864
|
return {
|
|
2862
2865
|
...entry,
|
|
2863
2866
|
activity,
|
|
@@ -2876,6 +2879,7 @@ function assembleMSTeamsInboundFacts(params) {
|
|
|
2876
2879
|
teamId,
|
|
2877
2880
|
graphChannelId: activity.channelData?.channel?.id?.trim() || conversationId,
|
|
2878
2881
|
threadId,
|
|
2882
|
+
historyKey: threadId ? `${conversationId}:thread:${threadId}` : conversationId,
|
|
2879
2883
|
conversationRef: buildStoredConversationReference({
|
|
2880
2884
|
activity,
|
|
2881
2885
|
conversationId,
|
|
@@ -3149,7 +3153,7 @@ function createMSTeamsMessageHandler(deps) {
|
|
|
3149
3153
|
cfg,
|
|
3150
3154
|
channel: "msteams"
|
|
3151
3155
|
});
|
|
3152
|
-
const historyLimit =
|
|
3156
|
+
const historyLimit = (0, openclaw_plugin_sdk_number_runtime.resolvePromptHistoryLimit)(msteamsCfg?.historyLimit ?? cfg.messages?.groupChat?.historyLimit);
|
|
3153
3157
|
const conversationHistories = /* @__PURE__ */ new Map();
|
|
3154
3158
|
const readConfig = (0, openclaw_plugin_sdk_runtime_config_snapshot.createRuntimeConfigReader)(cfg);
|
|
3155
3159
|
const resolveDebounceMs = () => core.channel.debounce.resolveInboundDebounceMs({
|
|
@@ -3157,10 +3161,7 @@ function createMSTeamsMessageHandler(deps) {
|
|
|
3157
3161
|
channel: "msteams"
|
|
3158
3162
|
});
|
|
3159
3163
|
const handleTeamsMessageNow = async (params) => {
|
|
3160
|
-
const facts = assembleMSTeamsInboundFacts(
|
|
3161
|
-
entry: params,
|
|
3162
|
-
mediaMaxBytes
|
|
3163
|
-
});
|
|
3164
|
+
const facts = assembleMSTeamsInboundFacts(params);
|
|
3164
3165
|
const { context, activity, rawText, text, attachments, advertisedMedia, rawBody, quoteInfo, from, conversation, attachmentTypes, htmlSummary, conversationId, conversationMessageId, conversationType, isChannel, teamId, conversationRef } = facts;
|
|
3165
3166
|
const historyBody = [text, (0, openclaw_plugin_sdk_channel_inbound.formatMediaPlaceholderText)(advertisedMedia)].filter(Boolean).join("\n");
|
|
3166
3167
|
log.info("received message", {
|
|
@@ -3262,7 +3263,7 @@ function createMSTeamsMessageHandler(deps) {
|
|
|
3262
3263
|
if (historyBody) {
|
|
3263
3264
|
enqueuePrimaryMessageSystemEvent();
|
|
3264
3265
|
(0, openclaw_plugin_sdk_reply_history.createChannelHistoryWindow)({ historyMap: conversationHistories }).record({
|
|
3265
|
-
historyKey:
|
|
3266
|
+
historyKey: facts.historyKey,
|
|
3266
3267
|
limit: historyLimit,
|
|
3267
3268
|
entry: {
|
|
3268
3269
|
sender: senderName,
|
|
@@ -3420,21 +3421,33 @@ function createMSTeamsReactionHandler(deps) {
|
|
|
3420
3421
|
}
|
|
3421
3422
|
const rawConversationId = activity.conversation?.id ?? "";
|
|
3422
3423
|
const conversationId = require_resolve_allowlist.normalizeMSTeamsConversationId(rawConversationId);
|
|
3423
|
-
const
|
|
3424
|
-
const isGroupChat = conversationType === "groupChat" || activity.conversation?.isGroup === true;
|
|
3425
|
-
const isChannel = conversationType === "channel";
|
|
3426
|
-
const isDirectMessage = !isGroupChat && !isChannel;
|
|
3424
|
+
const isChannel = activity.conversation?.conversationType === "channel";
|
|
3427
3425
|
const senderId = from.aadObjectId ?? from.id;
|
|
3428
3426
|
const senderName = from.name ?? from.id;
|
|
3427
|
+
const access = await resolveMSTeamsSenderAccess({
|
|
3428
|
+
cfg,
|
|
3429
|
+
activity
|
|
3430
|
+
});
|
|
3431
|
+
const { isDirectMessage, channelGate } = access;
|
|
3432
|
+
if (access.hasConflictingConversationScope) {
|
|
3433
|
+
log.info("dropping reaction (conflicting conversation scope)", { conversationId });
|
|
3434
|
+
return;
|
|
3435
|
+
}
|
|
3429
3436
|
if (msteamsCfg) {
|
|
3430
|
-
|
|
3431
|
-
cfg,
|
|
3432
|
-
activity
|
|
3433
|
-
});
|
|
3434
|
-
if (senderAccess.senderAccess.decision !== "allow") {
|
|
3437
|
+
if (access.senderAccess.decision !== "allow") {
|
|
3435
3438
|
log.debug?.("dropping reaction (access denied)", {
|
|
3436
3439
|
sender: senderId,
|
|
3437
|
-
reason:
|
|
3440
|
+
reason: access.senderAccess.reasonCode
|
|
3441
|
+
});
|
|
3442
|
+
return;
|
|
3443
|
+
}
|
|
3444
|
+
if (!isDirectMessage && channelGate.allowlistConfigured && !channelGate.allowed) {
|
|
3445
|
+
log.info("dropping reaction (not in team/channel allowlist)", {
|
|
3446
|
+
conversationId,
|
|
3447
|
+
teamKey: channelGate.teamKey ?? "none",
|
|
3448
|
+
channelKey: channelGate.channelKey ?? "none",
|
|
3449
|
+
channelMatchKey: channelGate.channelMatchKey ?? "none",
|
|
3450
|
+
channelMatchSource: channelGate.channelMatchSource ?? "none"
|
|
3438
3451
|
});
|
|
3439
3452
|
return;
|
|
3440
3453
|
}
|
|
@@ -3449,6 +3462,11 @@ function createMSTeamsReactionHandler(deps) {
|
|
|
3449
3462
|
},
|
|
3450
3463
|
...teamId ? { teamId } : {}
|
|
3451
3464
|
});
|
|
3465
|
+
const sessionKey = require_thread_session.resolveMSTeamsRouteSessionKey({
|
|
3466
|
+
baseSessionKey: route.sessionKey,
|
|
3467
|
+
isChannel,
|
|
3468
|
+
conversationMessageId: require_resolve_allowlist.extractMSTeamsConversationMessageId(rawConversationId)
|
|
3469
|
+
});
|
|
3452
3470
|
const targetMessageId = activity.replyToId ?? "unknown";
|
|
3453
3471
|
for (const reaction of reactions) {
|
|
3454
3472
|
const reactionType = reaction.type ?? "unknown";
|
|
@@ -3462,7 +3480,7 @@ function createMSTeamsReactionHandler(deps) {
|
|
|
3462
3480
|
conversationId
|
|
3463
3481
|
});
|
|
3464
3482
|
core.system.enqueueSystemEvent(label, {
|
|
3465
|
-
sessionKey
|
|
3483
|
+
sessionKey,
|
|
3466
3484
|
contextKey: `msteams:reaction:${conversationId}:${targetMessageId}:${senderId}:${reactionType}:${direction}`
|
|
3467
3485
|
});
|
|
3468
3486
|
}
|
|
@@ -3523,8 +3541,15 @@ async function isInvokeAuthorized(params) {
|
|
|
3523
3541
|
activity: context.activity
|
|
3524
3542
|
});
|
|
3525
3543
|
const { msteamsCfg, isDirectMessage, conversationId, senderId } = resolved;
|
|
3526
|
-
if (!msteamsCfg) return true;
|
|
3527
3544
|
const maybeInvokeName = includeInvokeName ? { name: context.activity.name } : void 0;
|
|
3545
|
+
if (resolved.hasConflictingConversationScope) {
|
|
3546
|
+
deps.log.info("dropping invoke (conflicting conversation scope)", {
|
|
3547
|
+
conversationId,
|
|
3548
|
+
...maybeInvokeName
|
|
3549
|
+
});
|
|
3550
|
+
return false;
|
|
3551
|
+
}
|
|
3552
|
+
if (!msteamsCfg) return true;
|
|
3528
3553
|
if (isDirectMessage && resolved.senderAccess.decision !== "allow") {
|
|
3529
3554
|
deps.log.debug?.(deniedLogs.dm, {
|
|
3530
3555
|
sender: senderId,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_runtime = require("./runtime-gZTAuFux.cjs");
|
|
2
|
-
const require_polls = require("./polls-
|
|
2
|
+
const require_polls = require("./polls-BJ4-4uZm.cjs");
|
|
3
3
|
let node_crypto = require("node:crypto");
|
|
4
4
|
//#region extensions/msteams/src/sso-token-store.ts
|
|
5
5
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
1
|
+
const require_resolve_allowlist = require("./resolve-allowlist-CHzaaWiC.cjs");
|
|
2
2
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
3
3
|
let openclaw_plugin_sdk_approval_auth_runtime = require("openclaw/plugin-sdk/approval-auth-runtime");
|
|
4
4
|
let openclaw_plugin_sdk_routing = require("openclaw/plugin-sdk/routing");
|
package/dist/api.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_channel = require("
|
|
3
|
-
const require_channel_setup = require("
|
|
2
|
+
const require_channel = require("./.setup/channel-BDp16XRR.cjs");
|
|
3
|
+
const require_channel_setup = require("./.setup/channel.setup-BVDfgdCc.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,3 +1,3 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_config_schema = require("
|
|
2
|
+
const require_config_schema = require("./.setup/config-schema-D22Lr1Qk.cjs");
|
|
3
3
|
exports.MSTeamsChannelConfigSchema = require_config_schema.MSTeamsChannelConfigSchema;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
require("
|
|
2
|
+
require("./.setup/secret-input-C65t6kjM.cjs");
|
|
3
3
|
let openclaw_plugin_sdk_secret_input = require("openclaw/plugin-sdk/secret-input");
|
|
4
4
|
//#region extensions/msteams/configured-state.ts
|
|
5
5
|
/** Mirror Teams auth-mode requirements without loading the Azure SDK or full channel. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_resolve_allowlist = require("
|
|
2
|
+
const require_resolve_allowlist = require("./.setup/resolve-allowlist-CHzaaWiC.cjs");
|
|
3
3
|
let openclaw_plugin_sdk_directory_runtime = require("openclaw/plugin-sdk/directory-runtime");
|
|
4
4
|
const msteamsDirectoryContractPlugin = {
|
|
5
5
|
id: "msteams",
|