@openclaw/msteams 2026.7.2-beta.7 → 2026.8.1-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.
- package/dist/adapter.runtime-DEYjslFX.cjs +309 -0
- package/dist/api.cjs +2 -2
- package/dist/{channel-C7QxRjBW.cjs → channel-DfCbi0d_.cjs} +205 -205
- package/dist/channel-plugin-api.cjs +1 -1
- package/dist/{channel.runtime-DjY6d_hd.cjs → channel.runtime-BJmueA4q.cjs} +91 -61
- package/dist/directory-contract-api.cjs +1 -1
- package/dist/doctor-contract-api.cjs +18 -17
- package/dist/{messenger-DTiaLTDO.cjs → messenger-BqA8G3pY.cjs} +21 -12
- package/dist/{oauth-CW6jVGp8.cjs → oauth-DktsbN22.cjs} +12 -25
- package/dist/{polls-BWKNpBSg.cjs → polls-DvuJvaDG.cjs} +6 -39
- package/dist/qa-runner-api.cjs +36 -0
- package/dist/{resolve-allowlist-CEj9sABO.cjs → resolve-allowlist-C6YcNC9a.cjs} +229 -167
- package/dist/rolldown-runtime-D6vf50IK.cjs +28 -0
- package/dist/secret-contract-api.cjs +6 -30
- package/dist/setup-plugin-api.cjs +2 -3
- package/dist/{setup-surface-ByWjaXEn.cjs → setup-surface-DAhGL2h8.cjs} +5 -10
- package/dist/{src-B_BdEvcr.cjs → src-Bz9wY0Mr.cjs} +344 -180
- package/dist/{sso-token-store-TKYk_Ms7.cjs → sso-token-store-ChhO1f4i.cjs} +1 -1
- package/openclaw.plugin.json +34 -8
- package/package.json +4 -5
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-D6vf50IK.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 = require("./channel-
|
|
6
|
-
const require_setup_surface = require("./setup-surface-
|
|
7
|
-
const
|
|
8
|
-
const
|
|
4
|
+
const require_resolve_allowlist = require("./resolve-allowlist-C6YcNC9a.cjs");
|
|
5
|
+
const require_channel = require("./channel-DfCbi0d_.cjs");
|
|
6
|
+
const require_setup_surface = require("./setup-surface-DAhGL2h8.cjs");
|
|
7
|
+
const require_polls = require("./polls-DvuJvaDG.cjs");
|
|
8
|
+
const require_sso_token_store = require("./sso-token-store-ChhO1f4i.cjs");
|
|
9
|
+
const require_messenger = require("./messenger-BqA8G3pY.cjs");
|
|
9
10
|
let openclaw_plugin_sdk_channel_outbound = require("openclaw/plugin-sdk/channel-outbound");
|
|
10
11
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
11
12
|
let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
|
|
@@ -14,10 +15,10 @@ let openclaw_plugin_sdk_ssrf_runtime = require("openclaw/plugin-sdk/ssrf-runtime
|
|
|
14
15
|
let openclaw_plugin_sdk_provider_http = require("openclaw/plugin-sdk/provider-http");
|
|
15
16
|
let openclaw_plugin_sdk_number_runtime = require("openclaw/plugin-sdk/number-runtime");
|
|
16
17
|
let openclaw_plugin_sdk_text_utility_runtime = require("openclaw/plugin-sdk/text-utility-runtime");
|
|
18
|
+
let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
|
|
17
19
|
let openclaw_plugin_sdk_routing = require("openclaw/plugin-sdk/routing");
|
|
18
20
|
let node_crypto = require("node:crypto");
|
|
19
|
-
node_crypto =
|
|
20
|
-
let openclaw_plugin_sdk_error_runtime = require("openclaw/plugin-sdk/error-runtime");
|
|
21
|
+
node_crypto = require_rolldown_runtime.__toESM(node_crypto, 1);
|
|
21
22
|
let openclaw_plugin_sdk_channel_inbound = require("openclaw/plugin-sdk/channel-inbound");
|
|
22
23
|
let openclaw_plugin_sdk_channel_ingress_runtime = require("openclaw/plugin-sdk/channel-ingress-runtime");
|
|
23
24
|
let openclaw_plugin_sdk_context_visibility_runtime = require("openclaw/plugin-sdk/context-visibility-runtime");
|
|
@@ -26,7 +27,9 @@ let openclaw_plugin_sdk_agent_runtime = require("openclaw/plugin-sdk/agent-runti
|
|
|
26
27
|
let openclaw_plugin_sdk_extension_shared = require("openclaw/plugin-sdk/extension-shared");
|
|
27
28
|
let openclaw_plugin_sdk_plugin_runtime = require("openclaw/plugin-sdk/plugin-runtime");
|
|
28
29
|
let openclaw_plugin_sdk_dedupe_runtime = require("openclaw/plugin-sdk/dedupe-runtime");
|
|
30
|
+
let openclaw_plugin_sdk_plugin_state_runtime = require("openclaw/plugin-sdk/plugin-state-runtime");
|
|
29
31
|
let openclaw_plugin_sdk_collection_runtime = require("openclaw/plugin-sdk/collection-runtime");
|
|
32
|
+
let openclaw_plugin_sdk_gateway_runtime = require("openclaw/plugin-sdk/gateway-runtime");
|
|
30
33
|
let openclaw_plugin_sdk_channel_pairing = require("openclaw/plugin-sdk/channel-pairing");
|
|
31
34
|
let openclaw_plugin_sdk_account_id = require("openclaw/plugin-sdk/account-id");
|
|
32
35
|
let openclaw_plugin_sdk_runtime_group_policy = require("openclaw/plugin-sdk/runtime-group-policy");
|
|
@@ -237,50 +240,53 @@ async function resolveMSTeamsSenderAccess(params) {
|
|
|
237
240
|
channelName: activity.channelData?.channel?.name,
|
|
238
241
|
allowNameMatching
|
|
239
242
|
});
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
...!isDirectMessage ? { "conversation-id": conversationId } : {}
|
|
252
|
-
}
|
|
253
|
-
},
|
|
254
|
-
conversation: {
|
|
255
|
-
kind: isDirectMessage ? "direct" : convType === "channel" ? "channel" : "group",
|
|
256
|
-
id: conversationId,
|
|
257
|
-
parentId: activity.channelData?.team?.id
|
|
258
|
-
},
|
|
259
|
-
route: (0, openclaw_plugin_sdk_channel_ingress_runtime.channelIngressRoutes)(!isDirectMessage && channelGate.allowlistConfigured && {
|
|
260
|
-
id: "msteams:team-channel",
|
|
261
|
-
kind: "nestedAllowlist",
|
|
262
|
-
allowed: channelGate.allowed,
|
|
263
|
-
precedence: 0,
|
|
264
|
-
matchId: "msteams-route",
|
|
265
|
-
...channelGate.allowed && groupPolicy === "allowlist" ? {
|
|
266
|
-
senderPolicy: "deny-when-empty",
|
|
267
|
-
senderAllowFromSource: "effective-group"
|
|
268
|
-
} : {}
|
|
269
|
-
}),
|
|
270
|
-
dmPolicy,
|
|
271
|
-
groupPolicy,
|
|
272
|
-
policy: {
|
|
273
|
-
groupAllowFromFallbackToAllowFrom: true,
|
|
274
|
-
mutableIdentifierMatching: allowNameMatching ? "enabled" : "disabled"
|
|
275
|
-
},
|
|
276
|
-
allowFrom: configuredDmAllowFrom,
|
|
277
|
-
groupAllowFrom,
|
|
278
|
-
command: {
|
|
279
|
-
allowTextCommands: true,
|
|
280
|
-
hasControlCommand: params.hasControlCommand === true,
|
|
281
|
-
directGroupAllowFrom: isDirectMessage ? "effective" : "none"
|
|
243
|
+
const resolved = await (0, openclaw_plugin_sdk_channel_ingress_runtime.resolveStableChannelMessageIngress)({
|
|
244
|
+
channelId: "msteams",
|
|
245
|
+
accountId: pairing.accountId,
|
|
246
|
+
identity: msteamsIngressIdentity,
|
|
247
|
+
cfg: params.cfg,
|
|
248
|
+
readStoreAllowFrom: pairing.readAllowFromStore,
|
|
249
|
+
subject: {
|
|
250
|
+
stableId: senderId,
|
|
251
|
+
aliases: {
|
|
252
|
+
"sender-name": senderName,
|
|
253
|
+
...!isDirectMessage ? { "conversation-id": conversationId } : {}
|
|
282
254
|
}
|
|
255
|
+
},
|
|
256
|
+
conversation: {
|
|
257
|
+
kind: isDirectMessage ? "direct" : convType === "channel" ? "channel" : "group",
|
|
258
|
+
id: conversationId,
|
|
259
|
+
threadId: params.conversationThreadId
|
|
260
|
+
},
|
|
261
|
+
...params.contextBinding ? { contextBinding: params.contextBinding } : {},
|
|
262
|
+
route: (0, openclaw_plugin_sdk_channel_ingress_runtime.channelIngressRoutes)(!isDirectMessage && channelGate.allowlistConfigured && {
|
|
263
|
+
id: "msteams:team-channel",
|
|
264
|
+
kind: "nestedAllowlist",
|
|
265
|
+
allowed: channelGate.allowed,
|
|
266
|
+
precedence: 0,
|
|
267
|
+
matchId: "msteams-route",
|
|
268
|
+
...channelGate.allowed && groupPolicy === "allowlist" ? {
|
|
269
|
+
senderPolicy: "deny-when-empty",
|
|
270
|
+
senderAllowFromSource: "effective-group"
|
|
271
|
+
} : {}
|
|
283
272
|
}),
|
|
273
|
+
dmPolicy,
|
|
274
|
+
groupPolicy,
|
|
275
|
+
policy: {
|
|
276
|
+
groupAllowFromFallbackToAllowFrom: true,
|
|
277
|
+
mutableIdentifierMatching: allowNameMatching ? "enabled" : "disabled"
|
|
278
|
+
},
|
|
279
|
+
allowFrom: configuredDmAllowFrom,
|
|
280
|
+
groupAllowFrom,
|
|
281
|
+
command: {
|
|
282
|
+
allowTextCommands: true,
|
|
283
|
+
hasControlCommand: params.hasControlCommand === true,
|
|
284
|
+
directGroupAllowFrom: isDirectMessage ? "effective" : "none"
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
return {
|
|
288
|
+
...resolved,
|
|
289
|
+
channelIngress: resolved,
|
|
284
290
|
pairing,
|
|
285
291
|
isDirectMessage,
|
|
286
292
|
conversationId,
|
|
@@ -381,7 +387,7 @@ async function admitMSTeamsMessage(params) {
|
|
|
381
387
|
params.log.debug?.("dropping group message (groupPolicy: allowlist, no allowlist)", { conversationId: params.conversationId });
|
|
382
388
|
return null;
|
|
383
389
|
}
|
|
384
|
-
if (!senderAccess.allowed
|
|
390
|
+
if (!senderAccess.allowed) {
|
|
385
391
|
const allowMatch = require_channel.resolveMSTeamsAllowlistMatch({
|
|
386
392
|
allowFrom: effectiveGroupAllowFrom,
|
|
387
393
|
senderId,
|
|
@@ -473,7 +479,7 @@ async function fetchBotFrameworkAttachmentInfo(params) {
|
|
|
473
479
|
timeoutMs: require_resolve_allowlist.resolveMSTeamsRequestTimeoutMs(params.deadline)
|
|
474
480
|
});
|
|
475
481
|
} catch (err) {
|
|
476
|
-
params.logger?.warn?.("msteams botFramework attachmentInfo fetch failed", { error:
|
|
482
|
+
params.logger?.warn?.("msteams botFramework attachmentInfo fetch failed", { error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err) });
|
|
477
483
|
return;
|
|
478
484
|
}
|
|
479
485
|
if (!response.ok) {
|
|
@@ -484,7 +490,7 @@ async function fetchBotFrameworkAttachmentInfo(params) {
|
|
|
484
490
|
try {
|
|
485
491
|
return await (0, openclaw_plugin_sdk_provider_http.readProviderJsonResponse)(response, "msteams botFramework attachmentInfo");
|
|
486
492
|
} catch (err) {
|
|
487
|
-
params.logger?.warn?.("msteams botFramework attachmentInfo parse failed", { error:
|
|
493
|
+
params.logger?.warn?.("msteams botFramework attachmentInfo parse failed", { error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err) });
|
|
488
494
|
return;
|
|
489
495
|
}
|
|
490
496
|
}
|
|
@@ -506,7 +512,7 @@ async function saveBotFrameworkAttachmentView(params) {
|
|
|
506
512
|
timeoutMs: require_resolve_allowlist.resolveMSTeamsRequestTimeoutMs(params.deadline)
|
|
507
513
|
});
|
|
508
514
|
} catch (err) {
|
|
509
|
-
params.logger?.warn?.("msteams botFramework attachmentView fetch failed", { error:
|
|
515
|
+
params.logger?.warn?.("msteams botFramework attachmentView fetch failed", { error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err) });
|
|
510
516
|
return;
|
|
511
517
|
}
|
|
512
518
|
if (!response.ok) {
|
|
@@ -519,7 +525,7 @@ async function saveBotFrameworkAttachmentView(params) {
|
|
|
519
525
|
contentLength = (0, openclaw_plugin_sdk_media_runtime.parseMediaContentLength)(response.headers.get("content-length"));
|
|
520
526
|
} catch (err) {
|
|
521
527
|
await response.body?.cancel().catch(() => void 0);
|
|
522
|
-
params.logger?.warn?.("msteams botFramework attachmentView invalid content-length", { error:
|
|
528
|
+
params.logger?.warn?.("msteams botFramework attachmentView invalid content-length", { error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err) });
|
|
523
529
|
return;
|
|
524
530
|
}
|
|
525
531
|
if (contentLength !== null && contentLength > params.maxBytes) {
|
|
@@ -536,7 +542,7 @@ async function saveBotFrameworkAttachmentView(params) {
|
|
|
536
542
|
originalFilename: params.preserveFilenames ? params.fileNameHint : void 0
|
|
537
543
|
});
|
|
538
544
|
} catch (err) {
|
|
539
|
-
params.logger?.warn?.("msteams botFramework attachmentView save failed", { error:
|
|
545
|
+
params.logger?.warn?.("msteams botFramework attachmentView save failed", { error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err) });
|
|
540
546
|
return;
|
|
541
547
|
} finally {
|
|
542
548
|
await response.body?.cancel().catch(() => void 0);
|
|
@@ -564,7 +570,7 @@ async function downloadMSTeamsBotFrameworkAttachment(params) {
|
|
|
564
570
|
work: () => tokenProvider.getAccessToken(BOT_FRAMEWORK_SCOPE)
|
|
565
571
|
});
|
|
566
572
|
} catch (err) {
|
|
567
|
-
params.logger?.warn?.("msteams botFramework token acquisition failed", { error:
|
|
573
|
+
params.logger?.warn?.("msteams botFramework token acquisition failed", { error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err) });
|
|
568
574
|
return;
|
|
569
575
|
}
|
|
570
576
|
if (!accessToken) return;
|
|
@@ -665,7 +671,7 @@ async function downloadMSTeamsBotFrameworkAttachments(params) {
|
|
|
665
671
|
sourceId: attachmentId
|
|
666
672
|
});
|
|
667
673
|
params.logger?.warn?.("msteams botFramework attachment download failed", {
|
|
668
|
-
error:
|
|
674
|
+
error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err),
|
|
669
675
|
attachmentId
|
|
670
676
|
});
|
|
671
677
|
}
|
|
@@ -878,9 +884,6 @@ function scopeCandidatesForUrl(url) {
|
|
|
878
884
|
return ["https://api.botframework.com", "https://graph.microsoft.com"];
|
|
879
885
|
}
|
|
880
886
|
}
|
|
881
|
-
function isRedirectStatus(status) {
|
|
882
|
-
return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
|
|
883
|
-
}
|
|
884
887
|
async function resolveInlineDataImageMime(inline) {
|
|
885
888
|
const mime = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(await require_runtime.getMSTeamsRuntime().media.detectMime({
|
|
886
889
|
buffer: inline.data,
|
|
@@ -903,7 +906,7 @@ async function fetchWithAuthFallback(params) {
|
|
|
903
906
|
const tokenProvider = params.tokenProvider;
|
|
904
907
|
if (firstAttempt.status !== 401 && firstAttempt.status !== 403) return firstAttempt;
|
|
905
908
|
if (!require_resolve_allowlist.isUrlAllowed(params.url, params.policy.authAllowHosts)) return firstAttempt;
|
|
906
|
-
|
|
909
|
+
let fallbackAttempt = firstAttempt;
|
|
907
910
|
const scopes = scopeCandidatesForUrl(params.url);
|
|
908
911
|
const fetchFn = params.fetchFn ?? fetch;
|
|
909
912
|
for (const scope of scopes) try {
|
|
@@ -926,15 +929,11 @@ async function fetchWithAuthFallback(params) {
|
|
|
926
929
|
resolveFn: params.resolveFn,
|
|
927
930
|
timeoutMs: require_resolve_allowlist.resolveMSTeamsRequestTimeoutMs(params.deadline)
|
|
928
931
|
});
|
|
929
|
-
|
|
930
|
-
if (isRedirectStatus(authAttempt.status)) return authAttempt;
|
|
931
|
-
|
|
932
|
-
await authAttempt.body?.cancel();
|
|
933
|
-
continue;
|
|
934
|
-
}
|
|
935
|
-
await authAttempt.body?.cancel();
|
|
932
|
+
await fallbackAttempt.body?.cancel().catch(() => void 0);
|
|
933
|
+
if (authAttempt.ok || require_resolve_allowlist.isRedirectStatus(authAttempt.status)) return authAttempt;
|
|
934
|
+
fallbackAttempt = authAttempt;
|
|
936
935
|
} catch {}
|
|
937
|
-
return
|
|
936
|
+
return fallbackAttempt;
|
|
938
937
|
}
|
|
939
938
|
/**
|
|
940
939
|
* Download all file attachments from a Teams message (images, documents, etc.).
|
|
@@ -1015,7 +1014,7 @@ async function downloadMSTeamsAttachments(params) {
|
|
|
1015
1014
|
}, candidate.sourceId));
|
|
1016
1015
|
} catch (err) {
|
|
1017
1016
|
out.push(withSourceId({ kind: candidate.mediaKind }, candidate.sourceId));
|
|
1018
|
-
params.logger?.warn?.("msteams inline attachment decode failed", { error:
|
|
1017
|
+
params.logger?.warn?.("msteams inline attachment decode failed", { error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err) });
|
|
1019
1018
|
}
|
|
1020
1019
|
continue;
|
|
1021
1020
|
}
|
|
@@ -1047,7 +1046,7 @@ async function downloadMSTeamsAttachments(params) {
|
|
|
1047
1046
|
out.push(withSourceId(media, candidate.sourceId));
|
|
1048
1047
|
} catch (err) {
|
|
1049
1048
|
out.push(withSourceId({ kind: candidate.mediaKind }, candidate.sourceId));
|
|
1050
|
-
const msg =
|
|
1049
|
+
const msg = (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err);
|
|
1051
1050
|
params.logger?.warn?.(`msteams attachment download failed host=${safeHostForLog(candidate.url)} error=${msg}`);
|
|
1052
1051
|
}
|
|
1053
1052
|
}
|
|
@@ -1086,6 +1085,10 @@ function buildMSTeamsGraphMessageUrl(params) {
|
|
|
1086
1085
|
if (!chatId) return;
|
|
1087
1086
|
return `${require_resolve_allowlist.GRAPH_ROOT}/chats/${encodeURIComponent(chatId)}/messages/${encodeURIComponent(messageId)}`;
|
|
1088
1087
|
}
|
|
1088
|
+
async function releaseGraphResponse(response, release) {
|
|
1089
|
+
if (!response.bodyUsed) response.body?.cancel().catch(() => void 0);
|
|
1090
|
+
await release();
|
|
1091
|
+
}
|
|
1089
1092
|
async function fetchGraphCollection(params) {
|
|
1090
1093
|
const fetchFn = params.fetchFn ?? fetch;
|
|
1091
1094
|
const { response, release } = await (0, openclaw_plugin_sdk_ssrf_runtime.fetchWithSsrFGuard)({
|
|
@@ -1098,13 +1101,10 @@ async function fetchGraphCollection(params) {
|
|
|
1098
1101
|
});
|
|
1099
1102
|
try {
|
|
1100
1103
|
const status = response.status;
|
|
1101
|
-
if (!response.ok) {
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
items: []
|
|
1106
|
-
};
|
|
1107
|
-
}
|
|
1104
|
+
if (!response.ok) return {
|
|
1105
|
+
status,
|
|
1106
|
+
items: []
|
|
1107
|
+
};
|
|
1108
1108
|
try {
|
|
1109
1109
|
return {
|
|
1110
1110
|
status,
|
|
@@ -1117,7 +1117,7 @@ async function fetchGraphCollection(params) {
|
|
|
1117
1117
|
};
|
|
1118
1118
|
}
|
|
1119
1119
|
} finally {
|
|
1120
|
-
await release
|
|
1120
|
+
await releaseGraphResponse(response, release);
|
|
1121
1121
|
}
|
|
1122
1122
|
}
|
|
1123
1123
|
function normalizeGraphAttachment(att) {
|
|
@@ -1149,7 +1149,7 @@ async function downloadGraphHostedContent(params) {
|
|
|
1149
1149
|
deadline: params.deadline
|
|
1150
1150
|
});
|
|
1151
1151
|
} catch (err) {
|
|
1152
|
-
params.logger?.warn?.("msteams graph hostedContents fetch failed", { error:
|
|
1152
|
+
params.logger?.warn?.("msteams graph hostedContents fetch failed", { error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err) });
|
|
1153
1153
|
return {
|
|
1154
1154
|
media: [],
|
|
1155
1155
|
count: 0
|
|
@@ -1194,11 +1194,11 @@ async function downloadGraphHostedContent(params) {
|
|
|
1194
1194
|
sourceId: item.id
|
|
1195
1195
|
});
|
|
1196
1196
|
} finally {
|
|
1197
|
-
await release
|
|
1197
|
+
await releaseGraphResponse(valRes, release);
|
|
1198
1198
|
}
|
|
1199
1199
|
} catch (err) {
|
|
1200
1200
|
out.push(createGraphHostedContentFact(item));
|
|
1201
|
-
params.logger?.warn?.("msteams graph hostedContent value fetch failed", { error:
|
|
1201
|
+
params.logger?.warn?.("msteams graph hostedContent value fetch failed", { error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err) });
|
|
1202
1202
|
continue;
|
|
1203
1203
|
}
|
|
1204
1204
|
}
|
|
@@ -1227,9 +1227,9 @@ async function downloadMSTeamsGraphMedia(params) {
|
|
|
1227
1227
|
} catch (err) {
|
|
1228
1228
|
params.logger?.debug?.("graph media token acquisition failed", {
|
|
1229
1229
|
messageUrl,
|
|
1230
|
-
error:
|
|
1230
|
+
error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err)
|
|
1231
1231
|
});
|
|
1232
|
-
params.logger?.warn?.("msteams graph token acquisition failed", { error:
|
|
1232
|
+
params.logger?.warn?.("msteams graph token acquisition failed", { error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err) });
|
|
1233
1233
|
return {
|
|
1234
1234
|
media: [],
|
|
1235
1235
|
messageUrl,
|
|
@@ -1260,10 +1260,10 @@ async function downloadMSTeamsGraphMedia(params) {
|
|
|
1260
1260
|
} catch (err) {
|
|
1261
1261
|
params.logger?.debug?.("graph media message parse failed", {
|
|
1262
1262
|
messageUrl,
|
|
1263
|
-
error:
|
|
1263
|
+
error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err)
|
|
1264
1264
|
});
|
|
1265
1265
|
params.logger?.warn?.("msteams graph message parse failed", {
|
|
1266
|
-
error:
|
|
1266
|
+
error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err),
|
|
1267
1267
|
messageUrl
|
|
1268
1268
|
});
|
|
1269
1269
|
msgData = {};
|
|
@@ -1275,14 +1275,14 @@ async function downloadMSTeamsGraphMedia(params) {
|
|
|
1275
1275
|
status: messageStatus
|
|
1276
1276
|
});
|
|
1277
1277
|
} finally {
|
|
1278
|
-
await release
|
|
1278
|
+
await releaseGraphResponse(msgRes, release);
|
|
1279
1279
|
}
|
|
1280
1280
|
} catch (err) {
|
|
1281
1281
|
params.logger?.debug?.("graph media message fetch failed", {
|
|
1282
1282
|
messageUrl,
|
|
1283
|
-
error:
|
|
1283
|
+
error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err)
|
|
1284
1284
|
});
|
|
1285
|
-
params.logger?.warn?.("msteams graph message fetch failed", { error:
|
|
1285
|
+
params.logger?.warn?.("msteams graph message fetch failed", { error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err) });
|
|
1286
1286
|
}
|
|
1287
1287
|
for (const att of referenceAttachments) {
|
|
1288
1288
|
const name = att.name ?? "file";
|
|
@@ -1348,7 +1348,7 @@ async function downloadMSTeamsGraphMedia(params) {
|
|
|
1348
1348
|
} catch (err) {
|
|
1349
1349
|
sharePointMedia.push(unavailableMedia);
|
|
1350
1350
|
params.logger?.warn?.("msteams SharePoint reference download failed", {
|
|
1351
|
-
error:
|
|
1351
|
+
error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err),
|
|
1352
1352
|
name
|
|
1353
1353
|
});
|
|
1354
1354
|
}
|
|
@@ -1387,7 +1387,7 @@ async function downloadMSTeamsGraphMedia(params) {
|
|
|
1387
1387
|
});
|
|
1388
1388
|
} catch (err) {
|
|
1389
1389
|
params.logger?.warn?.("msteams graph attachment download failed", {
|
|
1390
|
-
error:
|
|
1390
|
+
error: (0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err),
|
|
1391
1391
|
messageUrl
|
|
1392
1392
|
});
|
|
1393
1393
|
}
|
|
@@ -1654,12 +1654,22 @@ function createTeamsReplyStreamController(params) {
|
|
|
1654
1654
|
let emittedText = "";
|
|
1655
1655
|
let acknowledgedText = "";
|
|
1656
1656
|
let acknowledgedStreamId;
|
|
1657
|
+
let replacementFinalPending = false;
|
|
1658
|
+
let replacementEmitFailed = false;
|
|
1659
|
+
let replacementSettlementPending = false;
|
|
1660
|
+
let replacementTextAwaitingAcknowledgement;
|
|
1661
|
+
let deferredReplacementEntries = [];
|
|
1662
|
+
let finalMetadataQueued = false;
|
|
1663
|
+
let failedSegmentFallbackPrepared = false;
|
|
1657
1664
|
const streamEvents = stream?.events;
|
|
1658
1665
|
let streamChunkSubscription;
|
|
1659
1666
|
if (typeof streamEvents?.on === "function" && typeof streamEvents.off === "function") streamChunkSubscription = streamEvents.on("chunk", (activity) => {
|
|
1660
|
-
|
|
1667
|
+
const replacementAcknowledgementPending = replacementTextAwaitingAcknowledgement !== void 0;
|
|
1668
|
+
const replacementAcknowledgement = typeof activity.text === "string" && replacementAcknowledgementPending && activity.text === replacementTextAwaitingAcknowledgement;
|
|
1669
|
+
if (activity.type !== "typing" || activity.channelData?.streamType !== "streaming" || !activity.id || !activity.text || acknowledgedStreamId !== void 0 && activity.id !== acknowledgedStreamId || (replacementAcknowledgementPending ? !replacementAcknowledgement : !activity.text.startsWith(acknowledgedText)) || !emittedText.startsWith(activity.text)) return;
|
|
1661
1670
|
acknowledgedStreamId = activity.id;
|
|
1662
1671
|
acknowledgedText = activity.text;
|
|
1672
|
+
if (activity.text === replacementTextAwaitingAcknowledgement) replacementTextAwaitingAcknowledgement = void 0;
|
|
1663
1673
|
});
|
|
1664
1674
|
const wasCanceled = () => canceledLocally || Boolean(stream?.canceled);
|
|
1665
1675
|
const releaseStreamChunkSubscription = () => {
|
|
@@ -1667,6 +1677,14 @@ function createTeamsReplyStreamController(params) {
|
|
|
1667
1677
|
streamEvents?.off(streamChunkSubscription);
|
|
1668
1678
|
streamChunkSubscription = void 0;
|
|
1669
1679
|
};
|
|
1680
|
+
const acknowledgedNativeDelivery = () => {
|
|
1681
|
+
if (!acknowledgedStreamId || !acknowledgedText) return { visibleReplySent: false };
|
|
1682
|
+
return {
|
|
1683
|
+
visibleReplySent: true,
|
|
1684
|
+
content: acknowledgedText,
|
|
1685
|
+
messageId: acknowledgedStreamId
|
|
1686
|
+
};
|
|
1687
|
+
};
|
|
1670
1688
|
const fallbackPayloadAfterAcknowledgedText = (payload) => {
|
|
1671
1689
|
if (!acknowledgedText || typeof payload.text !== "string" || !payload.text.startsWith(acknowledgedText)) return payload;
|
|
1672
1690
|
const remainingText = payload.text.slice(acknowledgedText.length);
|
|
@@ -1684,6 +1702,35 @@ function createTeamsReplyStreamController(params) {
|
|
|
1684
1702
|
mediaUrls: void 0
|
|
1685
1703
|
} : payload;
|
|
1686
1704
|
};
|
|
1705
|
+
const finalStreamActivity = (text) => ({
|
|
1706
|
+
type: "message",
|
|
1707
|
+
...text ? { text } : {},
|
|
1708
|
+
entities: [{
|
|
1709
|
+
type: "https://schema.org/Message",
|
|
1710
|
+
"@type": "Message",
|
|
1711
|
+
"@context": "https://schema.org",
|
|
1712
|
+
"@id": "",
|
|
1713
|
+
additionalType: ["AIGeneratedContent"]
|
|
1714
|
+
}],
|
|
1715
|
+
channelData: params.feedbackLoopEnabled ? { feedbackLoopEnabled: true } : {}
|
|
1716
|
+
});
|
|
1717
|
+
const deferredReplacementLogicalContent = () => {
|
|
1718
|
+
return deferredReplacementEntries.map((entry) => entry.payload.text).filter((text) => Boolean(text)).join("\n") || void 0;
|
|
1719
|
+
};
|
|
1720
|
+
const takeDeferredReplacementPayloads = (replacementFallback) => {
|
|
1721
|
+
const payloads = deferredReplacementEntries.flatMap((entry) => {
|
|
1722
|
+
if (entry.kind === "payload") return [entry.payload];
|
|
1723
|
+
const hasMedia = Boolean(entry.payload.mediaUrl || entry.payload.mediaUrls?.length);
|
|
1724
|
+
const text = replacementFallback?.text;
|
|
1725
|
+
if (!text && !hasMedia) return [];
|
|
1726
|
+
return [{
|
|
1727
|
+
...entry.payload,
|
|
1728
|
+
text: text || void 0
|
|
1729
|
+
}];
|
|
1730
|
+
});
|
|
1731
|
+
deferredReplacementEntries = [];
|
|
1732
|
+
return payloads;
|
|
1733
|
+
};
|
|
1687
1734
|
/**
|
|
1688
1735
|
* Render the current informative status line into the streaming card. Pulls
|
|
1689
1736
|
* the rotating "Thinking..." label from msteams config (or the plugin-sdk
|
|
@@ -1708,14 +1755,19 @@ function createTeamsReplyStreamController(params) {
|
|
|
1708
1755
|
canceledLocally = true;
|
|
1709
1756
|
return;
|
|
1710
1757
|
}
|
|
1711
|
-
params.log?.debug?.(`stream informative update failed: ${
|
|
1758
|
+
params.log?.debug?.(`stream informative update failed: ${(0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err)}`);
|
|
1712
1759
|
}
|
|
1713
1760
|
};
|
|
1714
1761
|
const progressDraftGate = (0, openclaw_plugin_sdk_channel_outbound.createChannelProgressDraftGate)({ onStart: renderInformativeUpdate });
|
|
1715
1762
|
return {
|
|
1716
1763
|
async onReplyStart() {},
|
|
1717
1764
|
onPartialReply(payload) {
|
|
1718
|
-
if (!stream || !payload.text || wasCanceled() || streamMode !== "partial"
|
|
1765
|
+
if (!stream || !payload.text || wasCanceled() || streamMode !== "partial") return;
|
|
1766
|
+
if (replacementSettlementPending && replacementFinalPending) {
|
|
1767
|
+
pendingFinalPayload = { text: payload.text };
|
|
1768
|
+
return;
|
|
1769
|
+
}
|
|
1770
|
+
if (streamFinalizationPending) return;
|
|
1719
1771
|
const fullText = payload.text;
|
|
1720
1772
|
let prefixLength = 0;
|
|
1721
1773
|
while (prefixLength < emittedText.length && prefixLength < fullText.length && emittedText[prefixLength] === fullText[prefixLength]) prefixLength += 1;
|
|
@@ -1724,7 +1776,13 @@ function createTeamsReplyStreamController(params) {
|
|
|
1724
1776
|
if (!delta) return;
|
|
1725
1777
|
if (previousRemainder.trim()) {
|
|
1726
1778
|
stream.clearText();
|
|
1727
|
-
streamFailed
|
|
1779
|
+
if (streamFailed) {
|
|
1780
|
+
streamFinalizationPending = true;
|
|
1781
|
+
return;
|
|
1782
|
+
}
|
|
1783
|
+
replacementFinalPending = true;
|
|
1784
|
+
replacementSettlementPending = true;
|
|
1785
|
+
pendingFinalPayload = { text: fullText };
|
|
1728
1786
|
streamFinalizationPending = true;
|
|
1729
1787
|
return;
|
|
1730
1788
|
}
|
|
@@ -1739,7 +1797,7 @@ function createTeamsReplyStreamController(params) {
|
|
|
1739
1797
|
return;
|
|
1740
1798
|
}
|
|
1741
1799
|
streamFailed = true;
|
|
1742
|
-
params.log?.warn?.(`msteams stream emit failed, falling back to block delivery: ${
|
|
1800
|
+
params.log?.warn?.(`msteams stream emit failed, falling back to block delivery: ${(0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err)}`);
|
|
1743
1801
|
}
|
|
1744
1802
|
},
|
|
1745
1803
|
/**
|
|
@@ -1781,6 +1839,49 @@ function createTeamsReplyStreamController(params) {
|
|
|
1781
1839
|
preparePayload(payload) {
|
|
1782
1840
|
if (!stream) return payload;
|
|
1783
1841
|
if (wasCanceled()) return;
|
|
1842
|
+
if (replacementSettlementPending) {
|
|
1843
|
+
if (!replacementFinalPending) {
|
|
1844
|
+
deferredReplacementEntries.push({
|
|
1845
|
+
kind: "payload",
|
|
1846
|
+
payload
|
|
1847
|
+
});
|
|
1848
|
+
return;
|
|
1849
|
+
}
|
|
1850
|
+
if (!payload.text) {
|
|
1851
|
+
deferredReplacementEntries.push({
|
|
1852
|
+
kind: "payload",
|
|
1853
|
+
payload
|
|
1854
|
+
});
|
|
1855
|
+
return;
|
|
1856
|
+
}
|
|
1857
|
+
replacementFinalPending = false;
|
|
1858
|
+
deferredReplacementEntries.push({
|
|
1859
|
+
kind: "replacement",
|
|
1860
|
+
payload
|
|
1861
|
+
});
|
|
1862
|
+
pendingFinalPayload = fallbackPayloadForSuppressedFinal(payload);
|
|
1863
|
+
try {
|
|
1864
|
+
replacementTextAwaitingAcknowledgement = payload.text;
|
|
1865
|
+
stream.emit(finalStreamActivity(payload.text));
|
|
1866
|
+
finalMetadataQueued = true;
|
|
1867
|
+
emittedText = payload.text;
|
|
1868
|
+
tokensEmitted = false;
|
|
1869
|
+
return;
|
|
1870
|
+
} catch (err) {
|
|
1871
|
+
replacementTextAwaitingAcknowledgement = void 0;
|
|
1872
|
+
tokensEmitted = false;
|
|
1873
|
+
if (isStreamCancelledError(err)) {
|
|
1874
|
+
canceledLocally = true;
|
|
1875
|
+
pendingFinalPayload = void 0;
|
|
1876
|
+
deferredReplacementEntries = [];
|
|
1877
|
+
return;
|
|
1878
|
+
}
|
|
1879
|
+
streamFailed = true;
|
|
1880
|
+
replacementEmitFailed = true;
|
|
1881
|
+
params.log?.warn?.(`msteams stream replacement failed, falling back to block delivery: ${(0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err)}`);
|
|
1882
|
+
return;
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1784
1885
|
if (tokensEmitted && !streamFailed) {
|
|
1785
1886
|
const hasMedia = Boolean(payload.mediaUrl || payload.mediaUrls?.length);
|
|
1786
1887
|
pendingFinalPayload = fallbackPayloadForSuppressedFinal(payload);
|
|
@@ -1792,11 +1893,9 @@ function createTeamsReplyStreamController(params) {
|
|
|
1792
1893
|
} : void 0;
|
|
1793
1894
|
}
|
|
1794
1895
|
if (streamFailed) {
|
|
1795
|
-
const fallback = fallbackPayloadAfterAcknowledgedText(payload);
|
|
1896
|
+
const fallback = failedSegmentFallbackPrepared ? payload : fallbackPayloadAfterAcknowledgedText(payload);
|
|
1897
|
+
failedSegmentFallbackPrepared = true;
|
|
1796
1898
|
pendingFinalPayload = void 0;
|
|
1797
|
-
acknowledgedText = "";
|
|
1798
|
-
acknowledgedStreamId = void 0;
|
|
1799
|
-
releaseStreamChunkSubscription();
|
|
1800
1899
|
return fallback;
|
|
1801
1900
|
}
|
|
1802
1901
|
if (streamMode === "progress" && payload.text) try {
|
|
@@ -1813,7 +1912,7 @@ function createTeamsReplyStreamController(params) {
|
|
|
1813
1912
|
canceledLocally = true;
|
|
1814
1913
|
return;
|
|
1815
1914
|
}
|
|
1816
|
-
params.log?.debug?.(`progress-mode finalize failed: ${
|
|
1915
|
+
params.log?.debug?.(`progress-mode finalize failed: ${(0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err)}`);
|
|
1817
1916
|
}
|
|
1818
1917
|
return payload;
|
|
1819
1918
|
},
|
|
@@ -1828,74 +1927,88 @@ function createTeamsReplyStreamController(params) {
|
|
|
1828
1927
|
releaseStreamChunkSubscription();
|
|
1829
1928
|
return { visibleReplySent: false };
|
|
1830
1929
|
}
|
|
1831
|
-
|
|
1930
|
+
let logicalContent;
|
|
1832
1931
|
try {
|
|
1833
1932
|
if (wasCanceled()) {
|
|
1834
1933
|
pendingFinalPayload = void 0;
|
|
1934
|
+
deferredReplacementEntries = [];
|
|
1835
1935
|
streamFinalizationPending = false;
|
|
1836
|
-
return
|
|
1837
|
-
visibleReplySent: content !== void 0,
|
|
1838
|
-
...content === void 0 ? {} : { content }
|
|
1839
|
-
};
|
|
1936
|
+
return acknowledgedNativeDelivery();
|
|
1840
1937
|
}
|
|
1841
|
-
if (!streamFinalizationPending) return
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
});
|
|
1938
|
+
if (!streamFinalizationPending) return acknowledgedNativeDelivery();
|
|
1939
|
+
if (replacementSettlementPending && replacementFinalPending && pendingFinalPayload?.text) {
|
|
1940
|
+
replacementFinalPending = false;
|
|
1941
|
+
deferredReplacementEntries.push({
|
|
1942
|
+
kind: "replacement",
|
|
1943
|
+
payload: pendingFinalPayload
|
|
1944
|
+
});
|
|
1945
|
+
replacementTextAwaitingAcknowledgement = pendingFinalPayload.text;
|
|
1946
|
+
logicalContent = deferredReplacementLogicalContent();
|
|
1947
|
+
stream.emit(finalStreamActivity(pendingFinalPayload.text));
|
|
1948
|
+
finalMetadataQueued = true;
|
|
1949
|
+
emittedText = pendingFinalPayload.text;
|
|
1950
|
+
}
|
|
1951
|
+
logicalContent ??= replacementSettlementPending ? deferredReplacementLogicalContent() : void 0;
|
|
1952
|
+
const content = pendingFinalPayload?.text ?? (emittedText || void 0);
|
|
1953
|
+
if (!finalMetadataQueued) stream.emit(finalStreamActivity());
|
|
1858
1954
|
const result = await stream.close();
|
|
1859
1955
|
streamFinalizationPending = false;
|
|
1860
1956
|
if (!result) {
|
|
1861
1957
|
const fallback = pendingFinalPayload;
|
|
1862
1958
|
pendingFinalPayload = void 0;
|
|
1863
|
-
const
|
|
1959
|
+
const canceled = wasCanceled();
|
|
1960
|
+
const replacementFallback = replacementSettlementPending && fallback && !canceled ? fallbackPayloadAfterAcknowledgedText(fallback) : void 0;
|
|
1961
|
+
const fallbackPayload = !replacementSettlementPending && fallback && !canceled ? fallbackPayloadAfterAcknowledgedText(fallback) : void 0;
|
|
1962
|
+
const postNativePayloads = replacementSettlementPending && !canceled ? takeDeferredReplacementPayloads(replacementFallback) : [];
|
|
1963
|
+
if (canceled) deferredReplacementEntries = [];
|
|
1864
1964
|
return {
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
...fallbackPayload ? { fallbackPayload } : {}
|
|
1965
|
+
...acknowledgedNativeDelivery(),
|
|
1966
|
+
...!canceled && logicalContent ? { logicalContent } : {},
|
|
1967
|
+
...fallbackPayload ? { fallbackPayload } : {},
|
|
1968
|
+
...postNativePayloads.length > 0 ? { postNativePayloads } : {}
|
|
1868
1969
|
};
|
|
1869
1970
|
}
|
|
1971
|
+
const replacementFallback = replacementSettlementPending && replacementEmitFailed && pendingFinalPayload ? fallbackPayloadAfterAcknowledgedText(pendingFinalPayload) : void 0;
|
|
1870
1972
|
pendingFinalPayload = void 0;
|
|
1871
|
-
const messageId = require_messenger.extractMessageId(result) ??
|
|
1973
|
+
const messageId = require_messenger.extractMessageId(result) ?? acknowledgedStreamId;
|
|
1974
|
+
const postNativePayloads = replacementSettlementPending ? takeDeferredReplacementPayloads(replacementFallback) : [];
|
|
1975
|
+
const nativeContent = replacementEmitFailed ? acknowledgedText || void 0 : content;
|
|
1872
1976
|
return {
|
|
1873
|
-
visibleReplySent: true,
|
|
1874
|
-
...
|
|
1875
|
-
...
|
|
1977
|
+
visibleReplySent: replacementEmitFailed ? Boolean(nativeContent) : true,
|
|
1978
|
+
...nativeContent === void 0 ? {} : { content: nativeContent },
|
|
1979
|
+
...logicalContent ? { logicalContent } : {},
|
|
1980
|
+
...messageId && (!replacementEmitFailed || nativeContent) ? { messageId } : {},
|
|
1981
|
+
...postNativePayloads.length > 0 ? { postNativePayloads } : {}
|
|
1876
1982
|
};
|
|
1877
1983
|
} catch (err) {
|
|
1878
1984
|
if (isStreamCancelledError(err)) {
|
|
1879
1985
|
canceledLocally = true;
|
|
1880
1986
|
pendingFinalPayload = void 0;
|
|
1987
|
+
deferredReplacementEntries = [];
|
|
1881
1988
|
streamFinalizationPending = false;
|
|
1882
|
-
return
|
|
1883
|
-
visibleReplySent: true,
|
|
1884
|
-
...content === void 0 ? {} : { content }
|
|
1885
|
-
};
|
|
1989
|
+
return acknowledgedNativeDelivery();
|
|
1886
1990
|
}
|
|
1887
1991
|
streamFailed = true;
|
|
1888
1992
|
streamFinalizationPending = false;
|
|
1889
|
-
params.log?.warn?.(`msteams stream finalize failed: ${
|
|
1993
|
+
params.log?.warn?.(`msteams stream finalize failed: ${(0, openclaw_plugin_sdk_error_runtime.coerceErrorMessage)(err)}`);
|
|
1890
1994
|
const fallback = pendingFinalPayload;
|
|
1891
1995
|
pendingFinalPayload = void 0;
|
|
1892
|
-
const
|
|
1996
|
+
const replacementFallback = replacementSettlementPending && fallback ? fallbackPayloadAfterAcknowledgedText(fallback) : void 0;
|
|
1997
|
+
const fallbackPayload = !replacementSettlementPending && fallback ? fallbackPayloadAfterAcknowledgedText(fallback) : void 0;
|
|
1998
|
+
const postNativePayloads = replacementSettlementPending ? takeDeferredReplacementPayloads(replacementFallback) : [];
|
|
1893
1999
|
return {
|
|
1894
|
-
|
|
1895
|
-
...
|
|
1896
|
-
...fallbackPayload ? { fallbackPayload } : {}
|
|
2000
|
+
...acknowledgedNativeDelivery(),
|
|
2001
|
+
...logicalContent ? { logicalContent } : {},
|
|
2002
|
+
...fallbackPayload ? { fallbackPayload } : {},
|
|
2003
|
+
...postNativePayloads.length > 0 ? { postNativePayloads } : {}
|
|
1897
2004
|
};
|
|
1898
2005
|
} finally {
|
|
2006
|
+
finalMetadataQueued = false;
|
|
2007
|
+
replacementEmitFailed = false;
|
|
2008
|
+
replacementFinalPending = false;
|
|
2009
|
+
replacementSettlementPending = false;
|
|
2010
|
+
replacementTextAwaitingAcknowledgement = void 0;
|
|
2011
|
+
deferredReplacementEntries = [];
|
|
1899
2012
|
releaseStreamChunkSubscription();
|
|
1900
2013
|
}
|
|
1901
2014
|
},
|
|
@@ -1998,6 +2111,7 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
1998
2111
|
const blockStreamingEnabled = blockStreamingResolved ?? false;
|
|
1999
2112
|
const typingIndicatorEnabled = typeof msteamsCfg?.typingIndicator === "boolean" ? msteamsCfg.typingIndicator : true;
|
|
2000
2113
|
const pendingDeliveries = [];
|
|
2114
|
+
const joinAcceptedContents = (contents) => contents.filter((content) => Boolean(content)).join("\n");
|
|
2001
2115
|
const sendMessages = async (messages) => {
|
|
2002
2116
|
return require_messenger.sendMSTeamsMessages({
|
|
2003
2117
|
replyStyle: params.replyStyle,
|
|
@@ -2046,11 +2160,13 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2046
2160
|
});
|
|
2047
2161
|
};
|
|
2048
2162
|
const deliveryOutcome = (delivery) => {
|
|
2049
|
-
const
|
|
2163
|
+
const acceptedParts = [...delivery.nativeResult ? [delivery.nativeResult] : [], ...delivery.blockResults];
|
|
2164
|
+
const messageIds = acceptedParts.flatMap((part) => part.messageIds);
|
|
2165
|
+
const content = delivery.errors.length > 0 ? joinAcceptedContents(acceptedParts.map((part) => part.content)) : delivery.content;
|
|
2050
2166
|
return {
|
|
2051
|
-
visibleReplySent:
|
|
2167
|
+
visibleReplySent: acceptedParts.length > 0,
|
|
2052
2168
|
...messageIds.length > 0 ? { messageIds } : {},
|
|
2053
|
-
...
|
|
2169
|
+
...acceptedParts.length > 0 && content !== void 0 ? { content } : {}
|
|
2054
2170
|
};
|
|
2055
2171
|
};
|
|
2056
2172
|
const settlePendingDelivery = (delivery) => {
|
|
@@ -2062,7 +2178,7 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2062
2178
|
return;
|
|
2063
2179
|
}
|
|
2064
2180
|
const error = delivery.errors.find((candidate) => !(candidate instanceof openclaw_plugin_sdk_error_runtime.PlatformMessageNotDispatchedError)) ?? delivery.errors[0];
|
|
2065
|
-
delivery.finalization.reject(
|
|
2181
|
+
delivery.finalization.reject(outcome.visibleReplySent ? (0, openclaw_plugin_sdk_channel_inbound.createChannelPartialDeliveryError)(error, {
|
|
2066
2182
|
...outcome,
|
|
2067
2183
|
visibleReplySent: true
|
|
2068
2184
|
}) : error);
|
|
@@ -2072,12 +2188,11 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2072
2188
|
messages,
|
|
2073
2189
|
finalization: (0, openclaw_plugin_sdk_extension_shared.createDeferred)(),
|
|
2074
2190
|
content: payload.text,
|
|
2191
|
+
blockResults: [],
|
|
2075
2192
|
native,
|
|
2076
2193
|
nativeSettled: !native,
|
|
2077
2194
|
blockSettled: messages.length === 0,
|
|
2078
2195
|
settled: false,
|
|
2079
|
-
visibleReplySent: false,
|
|
2080
|
-
messageIds: [],
|
|
2081
2196
|
errors: []
|
|
2082
2197
|
};
|
|
2083
2198
|
pendingDeliveries.push(delivery);
|
|
@@ -2093,9 +2208,11 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2093
2208
|
const sentIds = [];
|
|
2094
2209
|
for (const msg of toSend) try {
|
|
2095
2210
|
const msgIds = await sendMessages([msg]);
|
|
2096
|
-
delivery.visibleReplySent ||= msgIds.length > 0;
|
|
2097
2211
|
const validIds = msgIds.filter((id) => id.trim() && id !== "unknown");
|
|
2098
|
-
delivery.
|
|
2212
|
+
if (msgIds.length > 0) delivery.blockResults.push({
|
|
2213
|
+
messageIds: validIds,
|
|
2214
|
+
...msg.text ? { content: msg.text } : {}
|
|
2215
|
+
});
|
|
2099
2216
|
sentIds.push(...validIds);
|
|
2100
2217
|
} catch (msgError) {
|
|
2101
2218
|
failed += 1;
|
|
@@ -2179,11 +2296,16 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2179
2296
|
settlePendingDelivery(nativeDelivery);
|
|
2180
2297
|
return;
|
|
2181
2298
|
}
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2299
|
+
if (nativeResult.visibleReplySent) nativeDelivery.nativeResult = {
|
|
2300
|
+
messageIds: nativeResult.messageId ? [nativeResult.messageId] : [],
|
|
2301
|
+
...nativeResult.content !== void 0 ? { content: nativeResult.content } : {}
|
|
2302
|
+
};
|
|
2303
|
+
const hasPostNativePayloads = Boolean(nativeResult.postNativePayloads?.length);
|
|
2304
|
+
if (nativeResult.logicalContent !== void 0) nativeDelivery.content = nativeResult.logicalContent;
|
|
2305
|
+
else if (nativeResult.content !== void 0 && (!nativeResult.fallbackPayload && !hasPostNativePayloads || nativeDelivery.content === void 0)) nativeDelivery.content = nativeResult.content;
|
|
2306
|
+
const afterNativePayloads = [...nativeResult.fallbackPayload ? [nativeResult.fallbackPayload] : [], ...nativeResult.postNativePayloads ?? []];
|
|
2307
|
+
if (afterNativePayloads.length > 0) {
|
|
2308
|
+
nativeDelivery.messages.push(...afterNativePayloads.flatMap((payload) => renderReplyPayload(payload)));
|
|
2187
2309
|
nativeDelivery.blockSettled = nativeDelivery.messages.length === 0;
|
|
2188
2310
|
}
|
|
2189
2311
|
nativeDelivery.nativeSettled = true;
|
|
@@ -2201,10 +2323,10 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2201
2323
|
const progressCallbacks = streamController.hasStream() ? {
|
|
2202
2324
|
onReasoningStream: async (payload) => {
|
|
2203
2325
|
const text = typeof payload?.text === "string" ? payload.text : void 0;
|
|
2204
|
-
if (!text) return;
|
|
2326
|
+
if (!text) return false;
|
|
2205
2327
|
if (payload?.isReasoningSnapshot !== true) {
|
|
2206
2328
|
await streamController.pushProgressLine(text);
|
|
2207
|
-
return;
|
|
2329
|
+
return false;
|
|
2208
2330
|
}
|
|
2209
2331
|
await streamController.pushProgressLine((0, openclaw_plugin_sdk_channel_outbound.buildChannelProgressDraftLine)({
|
|
2210
2332
|
event: "item",
|
|
@@ -2213,6 +2335,7 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2213
2335
|
title: "Reasoning",
|
|
2214
2336
|
progressText: text
|
|
2215
2337
|
}));
|
|
2338
|
+
return false;
|
|
2216
2339
|
},
|
|
2217
2340
|
onToolStart: async (payload) => {
|
|
2218
2341
|
const name = typeof payload?.name === "string" ? payload.name : void 0;
|
|
@@ -2225,6 +2348,7 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2225
2348
|
...typeof payload?.phase === "string" ? { phase: payload.phase } : {},
|
|
2226
2349
|
...payload?.args && typeof payload.args === "object" ? { args: payload.args } : {}
|
|
2227
2350
|
}, detailMode === "explain" || detailMode === "raw" ? { detailMode } : void 0), name ? { toolName: name } : void 0);
|
|
2351
|
+
return false;
|
|
2228
2352
|
},
|
|
2229
2353
|
onItemEvent: async (payload) => {
|
|
2230
2354
|
await streamController.pushProgressLine((0, openclaw_plugin_sdk_channel_outbound.buildChannelProgressDraftLineForEntry)(msteamsCfg, {
|
|
@@ -2240,13 +2364,15 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2240
2364
|
...typeof payload?.progressText === "string" ? { progressText: payload.progressText } : {},
|
|
2241
2365
|
...typeof payload?.meta === "string" ? { meta: payload.meta } : {}
|
|
2242
2366
|
}));
|
|
2367
|
+
return false;
|
|
2243
2368
|
},
|
|
2244
2369
|
onPlanUpdate: async (payload) => {
|
|
2245
|
-
if (payload?.phase !== "update") return;
|
|
2370
|
+
if (payload?.phase !== "update") return false;
|
|
2246
2371
|
await streamController.pushPlanProgress((0, openclaw_plugin_sdk_channel_outbound.normalizeAgentPlanSteps)(payload.steps), { explanation: typeof payload.explanation === "string" ? payload.explanation : void 0 });
|
|
2372
|
+
return false;
|
|
2247
2373
|
},
|
|
2248
2374
|
onApprovalEvent: async (payload) => {
|
|
2249
|
-
if (payload?.phase !== "requested") return;
|
|
2375
|
+
if (payload?.phase !== "requested") return false;
|
|
2250
2376
|
await streamController.pushProgressLine((0, openclaw_plugin_sdk_channel_outbound.buildChannelProgressDraftLine)({
|
|
2251
2377
|
event: "approval",
|
|
2252
2378
|
phase: payload.phase,
|
|
@@ -2255,10 +2381,11 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2255
2381
|
...typeof payload?.reason === "string" ? { reason: payload.reason } : {},
|
|
2256
2382
|
...typeof payload?.message === "string" ? { message: payload.message } : {}
|
|
2257
2383
|
}));
|
|
2384
|
+
return false;
|
|
2258
2385
|
},
|
|
2259
2386
|
onCommandOutput: async (payload) => {
|
|
2260
|
-
if (payload?.phase !== "end") return;
|
|
2261
|
-
await streamController.pushProgressLine((0, openclaw_plugin_sdk_channel_outbound.
|
|
2387
|
+
if (payload?.phase !== "end") return false;
|
|
2388
|
+
await streamController.pushProgressLine((0, openclaw_plugin_sdk_channel_outbound.buildChannelProgressDraftLineForEntry)(msteamsCfg, {
|
|
2262
2389
|
event: "command-output",
|
|
2263
2390
|
...typeof payload?.itemId === "string" ? { itemId: payload.itemId } : {},
|
|
2264
2391
|
...typeof payload?.toolCallId === "string" ? { toolCallId: payload.toolCallId } : {},
|
|
@@ -2268,9 +2395,10 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2268
2395
|
...typeof payload?.status === "string" ? { status: payload.status } : {},
|
|
2269
2396
|
...typeof payload?.exitCode === "number" ? { exitCode: payload.exitCode } : {}
|
|
2270
2397
|
}));
|
|
2398
|
+
return false;
|
|
2271
2399
|
},
|
|
2272
2400
|
onPatchSummary: async (payload) => {
|
|
2273
|
-
if (payload?.phase !== "end") return;
|
|
2401
|
+
if (payload?.phase !== "end") return false;
|
|
2274
2402
|
await streamController.pushProgressLine((0, openclaw_plugin_sdk_channel_outbound.buildChannelProgressDraftLine)({
|
|
2275
2403
|
event: "patch",
|
|
2276
2404
|
...typeof payload?.itemId === "string" ? { itemId: payload.itemId } : {},
|
|
@@ -2283,6 +2411,7 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2283
2411
|
...Array.isArray(payload?.deleted) && payload.deleted.every((s) => typeof s === "string") ? { deleted: payload.deleted } : {},
|
|
2284
2412
|
...typeof payload?.summary === "string" ? { summary: payload.summary } : {}
|
|
2285
2413
|
}));
|
|
2414
|
+
return false;
|
|
2286
2415
|
}
|
|
2287
2416
|
} : {};
|
|
2288
2417
|
return {
|
|
@@ -2292,7 +2421,10 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2292
2421
|
},
|
|
2293
2422
|
delivery,
|
|
2294
2423
|
replyOptions: {
|
|
2295
|
-
...streamController.hasStream() ? { onPartialReply: (payload) =>
|
|
2424
|
+
...streamController.hasStream() ? { onPartialReply: (payload) => {
|
|
2425
|
+
streamController.onPartialReply(payload);
|
|
2426
|
+
return false;
|
|
2427
|
+
} } : {},
|
|
2296
2428
|
...progressCallbacks,
|
|
2297
2429
|
...shouldSuppressDefaultToolProgressMessages ? { suppressDefaultToolProgressMessages: true } : {},
|
|
2298
2430
|
disableBlockStreaming: blockStreamingResolved == null ? void 0 : !blockStreamingResolved,
|
|
@@ -2310,14 +2442,7 @@ const sentMessages = (0, openclaw_plugin_sdk_dedupe_runtime.createPersistentDedu
|
|
|
2310
2442
|
namespace: "msteams.sent-messages",
|
|
2311
2443
|
maxEntries: 1e3,
|
|
2312
2444
|
openStore: (options) => require_runtime.getOptionalMSTeamsRuntime()?.state.openKeyedStore(options),
|
|
2313
|
-
logError: (
|
|
2314
|
-
try {
|
|
2315
|
-
require_runtime.getOptionalMSTeamsRuntime()?.logging.getChildLogger({
|
|
2316
|
-
plugin: "msteams",
|
|
2317
|
-
feature: "sent-message-state"
|
|
2318
|
-
}).warn("Microsoft Teams persistent sent-message state failed", { error: String(error) });
|
|
2319
|
-
} catch {}
|
|
2320
|
-
},
|
|
2445
|
+
logError: (0, openclaw_plugin_sdk_plugin_state_runtime.createPluginStateErrorReporter)(require_runtime.getOptionalMSTeamsRuntime, "msteams", "sent-message-state", "Microsoft Teams persistent sent-message state failed"),
|
|
2321
2446
|
readTimestamp: (record) => record.sentAt
|
|
2322
2447
|
}
|
|
2323
2448
|
});
|
|
@@ -2389,7 +2514,21 @@ async function dispatchMSTeamsInboundTurn(params) {
|
|
|
2389
2514
|
}) : true;
|
|
2390
2515
|
const bodyForAgent = threadContext ? `[Thread history]\n${threadContext}\n[/Thread history]\n\n${agentBody}` : agentBody;
|
|
2391
2516
|
const nativeChannelId = isChannel && teamAadGroupId ? `${teamAadGroupId}/${graphChannelId}` : void 0;
|
|
2392
|
-
const
|
|
2517
|
+
const boundIngress = await resolveMSTeamsSenderAccess({
|
|
2518
|
+
cfg,
|
|
2519
|
+
activity,
|
|
2520
|
+
hasControlCommand: admission.isControlCommand,
|
|
2521
|
+
conversationThreadId: facts.threadId,
|
|
2522
|
+
contextBinding: {
|
|
2523
|
+
agentId: route.agentId,
|
|
2524
|
+
sessionKey: route.sessionKey,
|
|
2525
|
+
...activity.id ? { messageId: activity.id } : {},
|
|
2526
|
+
...nativeChannelId ? { nativeChannelId } : {},
|
|
2527
|
+
inboundEventKind: "user_request"
|
|
2528
|
+
}
|
|
2529
|
+
});
|
|
2530
|
+
const ctxPayload = core.channel.inbound.buildContext({
|
|
2531
|
+
channelIngress: boundIngress.channelIngress,
|
|
2393
2532
|
channel: "msteams",
|
|
2394
2533
|
contextVisibility: contextVisibilityMode,
|
|
2395
2534
|
supplemental: { quote: quoteInfo ? {
|
|
@@ -2422,6 +2561,8 @@ async function dispatchMSTeamsInboundTurn(params) {
|
|
|
2422
2561
|
},
|
|
2423
2562
|
reply: {
|
|
2424
2563
|
to: teamsTo,
|
|
2564
|
+
originatingTo: `conversation:${conversationId}`,
|
|
2565
|
+
messageThreadId: facts.threadId ?? void 0,
|
|
2425
2566
|
replyToId: activity.replyToId ?? void 0,
|
|
2426
2567
|
nativeChannelId
|
|
2427
2568
|
},
|
|
@@ -3660,6 +3801,24 @@ async function runMSTeamsFileConsentInvokeHandler(context, log) {
|
|
|
3660
3801
|
}
|
|
3661
3802
|
}
|
|
3662
3803
|
//#endregion
|
|
3804
|
+
//#region extensions/msteams/src/monitor-status.ts
|
|
3805
|
+
function publishMSTeamsBlocked(statusSink, lastError) {
|
|
3806
|
+
statusSink?.((0, openclaw_plugin_sdk_gateway_runtime.channelBlockedPatch)(lastError, { running: true }));
|
|
3807
|
+
}
|
|
3808
|
+
function publishMSTeamsReady(statusSink, now = Date.now()) {
|
|
3809
|
+
statusSink?.((0, openclaw_plugin_sdk_gateway_runtime.channelReadyPatch)({ lastConnectedAt: now }));
|
|
3810
|
+
}
|
|
3811
|
+
function publishMSTeamsRecovering(statusSink, lastError) {
|
|
3812
|
+
statusSink?.({
|
|
3813
|
+
connected: false,
|
|
3814
|
+
lifecycle: "recovering",
|
|
3815
|
+
lastError
|
|
3816
|
+
});
|
|
3817
|
+
}
|
|
3818
|
+
function publishMSTeamsStopped(statusSink) {
|
|
3819
|
+
statusSink?.((0, openclaw_plugin_sdk_gateway_runtime.channelStoppedPatch)());
|
|
3820
|
+
}
|
|
3821
|
+
//#endregion
|
|
3663
3822
|
//#region extensions/msteams/src/msteams-ingress.ts
|
|
3664
3823
|
const MSTEAMS_INGRESS_VERSION = 1;
|
|
3665
3824
|
const MSTEAMS_INGRESS_DRAIN_INTERVAL_MS = 500;
|
|
@@ -3695,9 +3854,6 @@ function parseClaimedActivity(payload, claimedId) {
|
|
|
3695
3854
|
if (facts.eventId !== claimedId) throw new MSTeamsIngressPayloadError("invalid-activity", "Microsoft Teams activity id changed after durable admission.");
|
|
3696
3855
|
return parsed;
|
|
3697
3856
|
}
|
|
3698
|
-
function errorText(error) {
|
|
3699
|
-
return error instanceof Error ? error.message : String(error);
|
|
3700
|
-
}
|
|
3701
3857
|
function createMSTeamsIngress(options) {
|
|
3702
3858
|
const queue = options.queue ?? require_runtime.getMSTeamsRuntime().state.openChannelIngressQueue({ accountId: options.accountId });
|
|
3703
3859
|
const liveContexts = /* @__PURE__ */ new Map();
|
|
@@ -3748,13 +3904,13 @@ function createMSTeamsIngress(options) {
|
|
|
3748
3904
|
};
|
|
3749
3905
|
return require_setup_surface.classifyMSTeamsSendError(error).kind === "auth" ? {
|
|
3750
3906
|
reason: "authentication-failed",
|
|
3751
|
-
message:
|
|
3907
|
+
message: (0, openclaw_plugin_sdk_error_runtime.formatErrorMessage)(error)
|
|
3752
3908
|
} : null;
|
|
3753
3909
|
},
|
|
3754
3910
|
onLog: (message) => options.runtime.error?.(`msteams: ${message}`)
|
|
3755
3911
|
},
|
|
3756
3912
|
createStoppedError: () => /* @__PURE__ */ new Error("Microsoft Teams ingress stopped."),
|
|
3757
|
-
onError: (error) => options.runtime.error?.(`msteams ingress drain failed: ${
|
|
3913
|
+
onError: (error) => options.runtime.error?.(`msteams ingress drain failed: ${(0, openclaw_plugin_sdk_error_runtime.formatErrorMessage)(error)}`)
|
|
3758
3914
|
});
|
|
3759
3915
|
let stopTask;
|
|
3760
3916
|
return {
|
|
@@ -3820,6 +3976,7 @@ async function monitorMSTeamsProvider(opts) {
|
|
|
3820
3976
|
let msteamsCfg = cfg.channels?.msteams;
|
|
3821
3977
|
if (!msteamsCfg?.enabled) {
|
|
3822
3978
|
log.debug?.("msteams provider disabled");
|
|
3979
|
+
publishMSTeamsBlocked(opts.statusSink, "Microsoft Teams provider is disabled");
|
|
3823
3980
|
return {
|
|
3824
3981
|
app: null,
|
|
3825
3982
|
shutdown: async () => {}
|
|
@@ -3828,6 +3985,7 @@ async function monitorMSTeamsProvider(opts) {
|
|
|
3828
3985
|
const creds = require_resolve_allowlist.resolveMSTeamsCredentials(msteamsCfg);
|
|
3829
3986
|
if (!creds) {
|
|
3830
3987
|
log.error("msteams credentials not configured");
|
|
3988
|
+
publishMSTeamsBlocked(opts.statusSink, "Microsoft Teams credentials are not configured");
|
|
3831
3989
|
return {
|
|
3832
3990
|
app: null,
|
|
3833
3991
|
shutdown: async () => {}
|
|
@@ -3922,9 +4080,10 @@ async function monitorMSTeamsProvider(opts) {
|
|
|
3922
4080
|
};
|
|
3923
4081
|
const port = msteamsCfg.webhook?.port ?? 3978;
|
|
3924
4082
|
const textLimit = core.channel.text.resolveTextChunkLimit(cfg, "msteams");
|
|
3925
|
-
const
|
|
3926
|
-
|
|
3927
|
-
|
|
4083
|
+
const mediaMaxBytes = (0, openclaw_plugin_sdk_media_runtime.resolveChannelMediaMaxBytes)({
|
|
4084
|
+
cfg,
|
|
4085
|
+
resolveChannelLimitMb: ({ cfg: channelCfg }) => channelCfg.channels?.msteams?.mediaMaxMb
|
|
4086
|
+
}) ?? 8 * 1024 * 1024;
|
|
3928
4087
|
const conversationStore = opts.conversationStore ?? require_polls.createMSTeamsConversationStoreState();
|
|
3929
4088
|
const pollStore = opts.pollStore ?? require_polls.createMSTeamsPollStoreState();
|
|
3930
4089
|
log.info(`starting provider (port ${port})`);
|
|
@@ -4171,17 +4330,21 @@ async function monitorMSTeamsProvider(opts) {
|
|
|
4171
4330
|
});
|
|
4172
4331
|
await app.initialize();
|
|
4173
4332
|
ingress.start();
|
|
4333
|
+
const privateQaRuntime = require_resolve_allowlist.resolveMSTeamsPrivateQaRuntime();
|
|
4174
4334
|
const httpServer = await new Promise((resolve, reject) => {
|
|
4175
|
-
const
|
|
4335
|
+
const onListen = (err) => err ? reject(err) : resolve(server);
|
|
4336
|
+
const server = privateQaRuntime ? expressApp.listen(port, privateQaRuntime.listenHost, onListen) : expressApp.listen(port, onListen);
|
|
4176
4337
|
}).catch(async (err) => {
|
|
4177
4338
|
log.error("msteams server error", { error: require_setup_surface.formatUnknownError(err) });
|
|
4178
4339
|
await ingress.stop();
|
|
4179
4340
|
throw err;
|
|
4180
4341
|
});
|
|
4181
4342
|
log.info(`msteams provider started on port ${port}`);
|
|
4343
|
+
publishMSTeamsReady(opts.statusSink);
|
|
4182
4344
|
applyMSTeamsWebhookTimeouts(httpServer);
|
|
4183
4345
|
httpServer.on("error", (err) => {
|
|
4184
4346
|
log.error("msteams server error", { error: require_setup_surface.formatUnknownError(err) });
|
|
4347
|
+
publishMSTeamsRecovering(opts.statusSink, require_setup_surface.formatUnknownError(err));
|
|
4185
4348
|
});
|
|
4186
4349
|
const shutdown = async () => {
|
|
4187
4350
|
log.info("shutting down msteams provider");
|
|
@@ -4192,6 +4355,7 @@ async function monitorMSTeamsProvider(opts) {
|
|
|
4192
4355
|
});
|
|
4193
4356
|
});
|
|
4194
4357
|
await ingress.stop();
|
|
4358
|
+
publishMSTeamsStopped(opts.statusSink);
|
|
4195
4359
|
};
|
|
4196
4360
|
await (0, openclaw_plugin_sdk_channel_outbound.keepHttpServerTaskAlive)({
|
|
4197
4361
|
server: httpServer,
|