@openclaw/msteams 2026.9.8 → 2026.10.1-beta.1
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/.setup/{adapter.runtime-BiWeMKXE.cjs → adapter.runtime-D0HYByze.cjs} +9 -7
- package/dist/.setup/{approval-handler.runtime-D1s7UR3U.cjs → approval-handler.runtime-C-RJ3wXc.cjs} +3 -3
- package/dist/.setup/{channel-ByzS7QJ0.cjs → channel-BFhXodl2.cjs} +61 -75
- package/dist/.setup/{channel.runtime-Baz8XDFs.cjs → channel.runtime-D9jrw2SN.cjs} +22 -46
- package/dist/.setup/{channel.setup-DL8lcWT_.cjs → channel.setup-ss0TO-ap.cjs} +30 -36
- package/dist/.setup/{conversation-store-state-B7JuyZTm.cjs → conversation-store-state-f7V8CVNy.cjs} +62 -128
- package/dist/.setup/{monitor-BJ7IyH4y.cjs → monitor-DfSPCRkk.cjs} +71 -171
- package/dist/.setup/{oauth-DQjOnJ4l.cjs → oauth-CYxMYIOQ.cjs} +1 -1
- package/dist/.setup/{reaction-types-CQ4oSUe7.cjs → reaction-types-B-GEv57k.cjs} +1 -1
- package/dist/.setup/{resolve-allowlist-Pl_NQFYH.cjs → resolve-allowlist-Ct9yxQUw.cjs} +16 -134
- package/dist/.setup/{send-VUM7Sryb.cjs → send-7VV1iCai.cjs} +24 -70
- package/dist/.setup/{setup-plugin-api-Dyf8kF-l.cjs → setup-plugin-api-B0OFG32J.cjs} +1 -1
- package/dist/.setup/{thread-session--rw3BTal.cjs → thread-session-ClI-lSyG.cjs} +1 -1
- package/dist/.setup/token-config-DOt3XwVa.cjs +139 -0
- package/dist/api.cjs +2 -2
- package/dist/channel-plugin-api.cjs +1 -1
- package/dist/directory-contract-api.cjs +3 -2
- package/dist/doctor-backup-resources.cjs +21 -0
- package/dist/doctor-contract-api.cjs +37 -19
- package/dist/qa-runner-api.cjs +1 -1
- package/dist/runtime-api.cjs +0 -20
- package/dist/setup-entry.cjs +1 -1
- package/dist/setup-plugin-api.cjs +1 -1
- package/package.json +4 -4
- package/dist/.setup/delegated-state-u-ywZyZT.cjs +0 -70
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-BloeesfJ.cjs");
|
|
2
2
|
const require_runtime = require("./runtime-gZTAuFux.cjs");
|
|
3
3
|
require("../runtime-api.cjs");
|
|
4
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
4
|
+
const require_resolve_allowlist = require("./resolve-allowlist-Ct9yxQUw.cjs");
|
|
5
5
|
const require_bot_framework_service_url = require("./bot-framework-service-url-BUhTe8F3.cjs");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
6
|
+
const require_token_config = require("./token-config-DOt3XwVa.cjs");
|
|
7
|
+
const require_channel = require("./channel-BFhXodl2.cjs");
|
|
8
|
+
const require_thread_session = require("./thread-session-ClI-lSyG.cjs");
|
|
9
|
+
const require_channel_setup = require("./channel.setup-ss0TO-ap.cjs");
|
|
9
10
|
const require_approval_card = require("./approval-card-DWPDItvq.cjs");
|
|
10
|
-
const require_conversation_store_state = require("./conversation-store-state-
|
|
11
|
-
const require_reaction_types = require("./reaction-types-
|
|
11
|
+
const require_conversation_store_state = require("./conversation-store-state-f7V8CVNy.cjs");
|
|
12
|
+
const require_reaction_types = require("./reaction-types-B-GEv57k.cjs");
|
|
12
13
|
let openclaw_plugin_sdk_channel_outbound = require("openclaw/plugin-sdk/channel-outbound");
|
|
13
14
|
let openclaw_plugin_sdk_string_coerce_runtime = require("openclaw/plugin-sdk/string-coerce-runtime");
|
|
14
15
|
let openclaw_plugin_sdk_allow_from = require("openclaw/plugin-sdk/allow-from");
|
|
@@ -31,6 +32,7 @@ let openclaw_plugin_sdk_channel_ingress_runtime = require("openclaw/plugin-sdk/c
|
|
|
31
32
|
let openclaw_plugin_sdk_context_visibility_runtime = require("openclaw/plugin-sdk/context-visibility-runtime");
|
|
32
33
|
let openclaw_plugin_sdk_reply_history = require("openclaw/plugin-sdk/reply-history");
|
|
33
34
|
let openclaw_plugin_sdk_runtime_config_snapshot = require("openclaw/plugin-sdk/runtime-config-snapshot");
|
|
35
|
+
let openclaw_plugin_sdk_request_url = require("openclaw/plugin-sdk/request-url");
|
|
34
36
|
let openclaw_plugin_sdk_agent_runtime = require("openclaw/plugin-sdk/agent-runtime");
|
|
35
37
|
let openclaw_plugin_sdk_extension_shared = require("openclaw/plugin-sdk/extension-shared");
|
|
36
38
|
let openclaw_plugin_sdk_plugin_runtime = require("openclaw/plugin-sdk/plugin-runtime");
|
|
@@ -80,19 +82,6 @@ async function storeSessionLearning(params) {
|
|
|
80
82
|
}
|
|
81
83
|
//#endregion
|
|
82
84
|
//#region extensions/msteams/src/feedback-reflection.ts
|
|
83
|
-
function buildFeedbackEvent(params) {
|
|
84
|
-
return {
|
|
85
|
-
type: "custom",
|
|
86
|
-
event: "feedback",
|
|
87
|
-
ts: Date.now(),
|
|
88
|
-
messageId: params.messageId,
|
|
89
|
-
value: params.value,
|
|
90
|
-
comment: params.comment,
|
|
91
|
-
sessionKey: params.sessionKey,
|
|
92
|
-
agentId: params.agentId,
|
|
93
|
-
conversationId: params.conversationId
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
85
|
/**
|
|
97
86
|
* Run a background reflection after negative feedback.
|
|
98
87
|
* This is designed to be called fire-and-forget (don't await in the invoke handler).
|
|
@@ -1102,7 +1091,7 @@ async function downloadMSTeamsAttachments(params) {
|
|
|
1102
1091
|
kind: candidate.mediaKind,
|
|
1103
1092
|
preserveFilenames: params.preserveFilenames,
|
|
1104
1093
|
fetchImpl: (input, init) => fetchWithAuthFallback({
|
|
1105
|
-
url:
|
|
1094
|
+
url: (0, openclaw_plugin_sdk_request_url.resolveRequestUrl)(input),
|
|
1106
1095
|
tokenProvider: params.tokenProvider,
|
|
1107
1096
|
fetchFn: params.fetchFn,
|
|
1108
1097
|
fetchFnSupportsDispatcher: params.fetchFnSupportsDispatcher,
|
|
@@ -1382,7 +1371,7 @@ async function downloadMSTeamsGraphMedia(params) {
|
|
|
1382
1371
|
contentTypeHint: "application/octet-stream",
|
|
1383
1372
|
preserveFilenames: params.preserveFilenames,
|
|
1384
1373
|
fetchImpl: async (input, init) => {
|
|
1385
|
-
const requestUrl =
|
|
1374
|
+
const requestUrl = (0, openclaw_plugin_sdk_request_url.resolveRequestUrl)(input);
|
|
1386
1375
|
const headers = require_resolve_allowlist.ensureUserAgentHeader(init?.headers);
|
|
1387
1376
|
require_resolve_allowlist.applyAuthorizationHeaderForUrl({
|
|
1388
1377
|
headers,
|
|
@@ -1494,11 +1483,8 @@ function mergeMSTeamsMediaFacts(nativeMedia, materializedMedia, options = {}) {
|
|
|
1494
1483
|
for (const [index, materialized] of materializedMedia.entries()) {
|
|
1495
1484
|
const sourceIndex = materialized.sourceId ? nativeIndexBySourceId.get(materialized.sourceId) : void 0;
|
|
1496
1485
|
const positionalIndex = options.positionallyAligned === false || index >= nativeMedia.length ? void 0 : index;
|
|
1497
|
-
const
|
|
1498
|
-
const
|
|
1499
|
-
const sameKindUnresolvedIndexes = mayUseFallbackOrder ? merged.slice(0, nativeSlotCount).flatMap((media, mediaIndex) => isEligibleUnresolved(media) && media.kind === materialized.kind ? [mediaIndex] : []) : [];
|
|
1500
|
-
const unresolvedIndexes = sameKindUnresolvedIndexes.length === 0 && mayUseFallbackOrder ? merged.slice(0, nativeSlotCount).flatMap((media, mediaIndex) => isEligibleUnresolved(media) ? [mediaIndex] : []) : [];
|
|
1501
|
-
const fallbackIndex = sameKindUnresolvedIndexes.length > 0 ? sameKindUnresolvedIndexes[0] : unresolvedIndexes.length === 1 ? unresolvedIndexes[0] : void 0;
|
|
1486
|
+
const unresolvedIndexes = options.positionallyAligned === false ? merged.slice(0, nativeSlotCount).flatMap((media, mediaIndex) => !media.path && !media.sourceId ? [mediaIndex] : []) : [];
|
|
1487
|
+
const fallbackIndex = unresolvedIndexes.find((mediaIndex) => merged[mediaIndex]?.kind === materialized.kind) ?? (unresolvedIndexes.length === 1 ? unresolvedIndexes[0] : void 0);
|
|
1502
1488
|
const targetIndex = sourceIndex ?? positionalIndex ?? fallbackIndex;
|
|
1503
1489
|
if (targetIndex === void 0) {
|
|
1504
1490
|
if (materialized.sourceId) nativeIndexBySourceId.set(materialized.sourceId, merged.length);
|
|
@@ -1683,21 +1669,7 @@ async function prepareMSTeamsInboundContent(params) {
|
|
|
1683
1669
|
function isStreamCancelledError(err) {
|
|
1684
1670
|
return err instanceof Error && err.name === "StreamCancelledError";
|
|
1685
1671
|
}
|
|
1686
|
-
/**
|
|
1687
|
-
* Bridges openclaw's reply pipeline callbacks to the SDK's `ctx.stream`.
|
|
1688
|
-
* Streaming is enabled for personal (DM) conversations only; group/channel
|
|
1689
|
-
* messages fall through to block delivery.
|
|
1690
|
-
*
|
|
1691
|
-
* Streaming modes (resolved from `cfg.channels.msteams.streaming.mode`):
|
|
1692
|
-
* - "partial" (default): per-token streaming via `stream.emit(text)`. Each
|
|
1693
|
-
* chunk goes onto the live preview card in Teams.
|
|
1694
|
-
* - "progress": no per-token streaming; the preview card carries an
|
|
1695
|
-
* informative status that updates as tools run (e.g. "Looking up the
|
|
1696
|
-
* schema..." → "Generating SQL..."). When tool-progress streaming is also
|
|
1697
|
-
* enabled, raw tool names appear as bullets above the label.
|
|
1698
|
-
* - "block": disable native streaming entirely; the reply lands as a regular
|
|
1699
|
-
* block message. We bypass the controller in that case.
|
|
1700
|
-
*/
|
|
1672
|
+
/** Bridge reply callbacks to the SDK stream; shared conversations use block delivery. */
|
|
1701
1673
|
function createTeamsReplyStreamController(params) {
|
|
1702
1674
|
const isPersonal = (0, openclaw_plugin_sdk_string_coerce_runtime.normalizeOptionalLowercaseString)(params.conversationType) === "personal";
|
|
1703
1675
|
const streamMode = (0, openclaw_plugin_sdk_channel_outbound.resolveChannelPreviewStreamMode)(params.msteamsConfig, "partial");
|
|
@@ -2111,7 +2083,6 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2111
2083
|
return require_conversation_store_state.sendMSTeamsMessages({
|
|
2112
2084
|
replyStyle: params.replyStyle,
|
|
2113
2085
|
app: params.app,
|
|
2114
|
-
appId: params.appId,
|
|
2115
2086
|
conversationRef: params.conversationRef,
|
|
2116
2087
|
context: params.context,
|
|
2117
2088
|
messages,
|
|
@@ -2373,7 +2344,7 @@ function createMSTeamsReplyDispatcher(params) {
|
|
|
2373
2344
|
//#region extensions/msteams/src/monitor-handler/inbound-dispatch.ts
|
|
2374
2345
|
async function dispatchMSTeamsInboundTurn(params) {
|
|
2375
2346
|
const core = require_runtime.getMSTeamsRuntime();
|
|
2376
|
-
const { cfg, runtime,
|
|
2347
|
+
const { cfg, runtime, app, tokenProvider, textLimit, log, logVerboseMessage, facts, admission, content, routing, thread, replyStyle, timestamp, contextVisibilityMode, conversationHistories, historyLimit } = params;
|
|
2377
2348
|
const { context, activity, rawBody, text, quoteInfo, conversationRef } = facts;
|
|
2378
2349
|
const { senderId, senderName, isDirectMessage, allowNameMatching, groupPolicy, commandAuthorized, effectiveGroupAllowFrom } = admission;
|
|
2379
2350
|
const { route } = routing;
|
|
@@ -2518,7 +2489,6 @@ async function dispatchMSTeamsInboundTurn(params) {
|
|
|
2518
2489
|
runtime,
|
|
2519
2490
|
log,
|
|
2520
2491
|
app,
|
|
2521
|
-
appId,
|
|
2522
2492
|
conversationRef,
|
|
2523
2493
|
context,
|
|
2524
2494
|
replyStyle,
|
|
@@ -3130,7 +3100,6 @@ function createMSTeamsMessageHandler(deps) {
|
|
|
3130
3100
|
await dispatchMSTeamsInboundTurn({
|
|
3131
3101
|
cfg: currentCfg,
|
|
3132
3102
|
runtime,
|
|
3133
|
-
appId,
|
|
3134
3103
|
app,
|
|
3135
3104
|
tokenProvider,
|
|
3136
3105
|
textLimit,
|
|
@@ -3224,10 +3193,6 @@ function createMSTeamsMessageHandler(deps) {
|
|
|
3224
3193
|
}
|
|
3225
3194
|
//#endregion
|
|
3226
3195
|
//#region extensions/msteams/src/monitor-handler/reaction-handler.ts
|
|
3227
|
-
/**
|
|
3228
|
-
* Create a handler for MS Teams reaction activities (reactionsAdded / reactionsRemoved).
|
|
3229
|
-
* The returned function accepts a turn context and a direction string.
|
|
3230
|
-
*/
|
|
3231
3196
|
function createMSTeamsReactionHandler(deps) {
|
|
3232
3197
|
const { cfg, log } = deps;
|
|
3233
3198
|
const core = require_runtime.getMSTeamsRuntime();
|
|
@@ -3314,17 +3279,11 @@ function createMSTeamsReactionHandler(deps) {
|
|
|
3314
3279
|
}
|
|
3315
3280
|
//#endregion
|
|
3316
3281
|
//#region extensions/msteams/src/welcome-card.ts
|
|
3317
|
-
/**
|
|
3318
|
-
* Builds an Adaptive Card for welcoming users when the bot is added to a conversation.
|
|
3319
|
-
*/
|
|
3320
3282
|
const DEFAULT_PROMPT_STARTERS = [
|
|
3321
3283
|
"What can you do?",
|
|
3322
3284
|
"Summarize my last meeting",
|
|
3323
3285
|
"Help me draft an email"
|
|
3324
3286
|
];
|
|
3325
|
-
/**
|
|
3326
|
-
* Build a welcome Adaptive Card for 1:1 personal chats.
|
|
3327
|
-
*/
|
|
3328
3287
|
function buildWelcomeCard(options) {
|
|
3329
3288
|
const botName = options?.botName || "OpenClaw";
|
|
3330
3289
|
const starters = options?.promptStarters?.length ? options.promptStarters : DEFAULT_PROMPT_STARTERS;
|
|
@@ -3351,23 +3310,20 @@ function buildWelcomeCard(options) {
|
|
|
3351
3310
|
}))
|
|
3352
3311
|
};
|
|
3353
3312
|
}
|
|
3354
|
-
/**
|
|
3355
|
-
* Build a brief welcome message for group chats (when the bot is @mentioned).
|
|
3356
|
-
*/
|
|
3357
3313
|
function buildGroupWelcomeText(botName) {
|
|
3358
3314
|
const name = botName || "OpenClaw";
|
|
3359
3315
|
return `Hi! I'm ${name}. Mention me with @${name} to get started.`;
|
|
3360
3316
|
}
|
|
3361
3317
|
//#endregion
|
|
3362
3318
|
//#region extensions/msteams/src/monitor-handler.ts
|
|
3363
|
-
async function
|
|
3364
|
-
const { context, deps,
|
|
3319
|
+
async function isMSTeamsInvokeAuthorized(params) {
|
|
3320
|
+
const { context, deps, invokeKind } = params;
|
|
3365
3321
|
const resolved = await resolveMSTeamsSenderAccess({
|
|
3366
3322
|
cfg: deps.cfg,
|
|
3367
3323
|
activity: context.activity
|
|
3368
3324
|
});
|
|
3369
3325
|
const { msteamsCfg, isDirectMessage, conversationId, senderId } = resolved;
|
|
3370
|
-
const maybeInvokeName =
|
|
3326
|
+
const maybeInvokeName = invokeKind === "feedback" ? void 0 : { name: context.activity.name };
|
|
3371
3327
|
if (resolved.hasConflictingConversationScope) {
|
|
3372
3328
|
deps.log.info("dropping invoke (conflicting conversation scope)", {
|
|
3373
3329
|
conversationId,
|
|
@@ -3377,7 +3333,7 @@ async function isInvokeAuthorized(params) {
|
|
|
3377
3333
|
}
|
|
3378
3334
|
if (!msteamsCfg) return true;
|
|
3379
3335
|
if (isDirectMessage && resolved.senderAccess.decision !== "allow") {
|
|
3380
|
-
deps.log.debug?.(
|
|
3336
|
+
deps.log.debug?.(`dropping ${invokeKind} invoke (dm sender not allowlisted)`, {
|
|
3381
3337
|
sender: senderId,
|
|
3382
3338
|
conversationId,
|
|
3383
3339
|
...maybeInvokeName
|
|
@@ -3385,7 +3341,7 @@ async function isInvokeAuthorized(params) {
|
|
|
3385
3341
|
return false;
|
|
3386
3342
|
}
|
|
3387
3343
|
if (!isDirectMessage && resolved.channelGate.allowlistConfigured && !resolved.channelGate.allowed) {
|
|
3388
|
-
deps.log.debug?.(
|
|
3344
|
+
deps.log.debug?.(`dropping ${invokeKind} invoke (not in team/channel allowlist)`, {
|
|
3389
3345
|
conversationId,
|
|
3390
3346
|
teamKey: resolved.channelGate.teamKey ?? "none",
|
|
3391
3347
|
channelKey: resolved.channelGate.channelKey ?? "none",
|
|
@@ -3394,7 +3350,7 @@ async function isInvokeAuthorized(params) {
|
|
|
3394
3350
|
return false;
|
|
3395
3351
|
}
|
|
3396
3352
|
if (!isDirectMessage && !resolved.senderAccess.allowed) {
|
|
3397
|
-
deps.log.debug?.(
|
|
3353
|
+
deps.log.debug?.(`dropping ${invokeKind} invoke (group sender not allowlisted)`, {
|
|
3398
3354
|
sender: senderId,
|
|
3399
3355
|
conversationId,
|
|
3400
3356
|
...maybeInvokeName
|
|
@@ -3403,41 +3359,6 @@ async function isInvokeAuthorized(params) {
|
|
|
3403
3359
|
}
|
|
3404
3360
|
return true;
|
|
3405
3361
|
}
|
|
3406
|
-
async function isFeedbackInvokeAuthorized(context, deps) {
|
|
3407
|
-
return isInvokeAuthorized({
|
|
3408
|
-
context,
|
|
3409
|
-
deps,
|
|
3410
|
-
deniedLogs: {
|
|
3411
|
-
dm: "dropping feedback invoke (dm sender not allowlisted)",
|
|
3412
|
-
channel: "dropping feedback invoke (not in team/channel allowlist)",
|
|
3413
|
-
group: "dropping feedback invoke (group sender not allowlisted)"
|
|
3414
|
-
}
|
|
3415
|
-
});
|
|
3416
|
-
}
|
|
3417
|
-
async function isSigninInvokeAuthorized(context, deps) {
|
|
3418
|
-
return isInvokeAuthorized({
|
|
3419
|
-
context,
|
|
3420
|
-
deps,
|
|
3421
|
-
deniedLogs: {
|
|
3422
|
-
dm: "dropping signin invoke (dm sender not allowlisted)",
|
|
3423
|
-
channel: "dropping signin invoke (not in team/channel allowlist)",
|
|
3424
|
-
group: "dropping signin invoke (group sender not allowlisted)"
|
|
3425
|
-
},
|
|
3426
|
-
includeInvokeName: true
|
|
3427
|
-
});
|
|
3428
|
-
}
|
|
3429
|
-
async function isCardActionInvokeAuthorized(context, deps) {
|
|
3430
|
-
return isInvokeAuthorized({
|
|
3431
|
-
context,
|
|
3432
|
-
deps,
|
|
3433
|
-
deniedLogs: {
|
|
3434
|
-
dm: "dropping card action invoke (dm sender not allowlisted)",
|
|
3435
|
-
channel: "dropping card action invoke (not in team/channel allowlist)",
|
|
3436
|
-
group: "dropping card action invoke (group sender not allowlisted)"
|
|
3437
|
-
},
|
|
3438
|
-
includeInvokeName: true
|
|
3439
|
-
});
|
|
3440
|
-
}
|
|
3441
3362
|
function createMSTeamsActivityHandler(deps) {
|
|
3442
3363
|
const handleTeamsMessage = createMSTeamsMessageHandler(deps);
|
|
3443
3364
|
const handleReaction = createMSTeamsReactionHandler(deps);
|
|
@@ -3510,21 +3431,7 @@ function createMSTeamsActivityHandler(deps) {
|
|
|
3510
3431
|
}
|
|
3511
3432
|
//#endregion
|
|
3512
3433
|
//#region extensions/msteams/src/feedback-invoke.ts
|
|
3513
|
-
/**
|
|
3514
|
-
* Run the message-submit (feedback) invoke handler.
|
|
3515
|
-
*
|
|
3516
|
-
* Teams delivers feedback (`actionName === "feedback"`) on AI-generated
|
|
3517
|
-
* messages as a `message/submitAction` invoke. The SDK wraps a void return
|
|
3518
|
-
* into the HTTP 200 InvokeResponse, so this function intentionally does
|
|
3519
|
-
* not ack itself — the legacy `ctx.sendActivity({ type: "invokeResponse",
|
|
3520
|
-
* … })` shape is gone (it became an outbound BF activity on the new SDK
|
|
3521
|
-
* instead of the HTTP response).
|
|
3522
|
-
*
|
|
3523
|
-
* Returns `true` if the invoke matched the feedback shape and was
|
|
3524
|
-
* consumed (whether or not it was authorized / written / reflected on),
|
|
3525
|
-
* `false` if the invoke didn't look like feedback at all and the caller
|
|
3526
|
-
* should fall through to other handlers.
|
|
3527
|
-
*/
|
|
3434
|
+
/** Return whether feedback consumed the invoke; the SDK owns its HTTP acknowledgement. */
|
|
3528
3435
|
async function runMSTeamsFeedbackInvokeHandler(context, deps) {
|
|
3529
3436
|
const activity = context.activity;
|
|
3530
3437
|
const value = activity.value;
|
|
@@ -3540,7 +3447,11 @@ async function runMSTeamsFeedbackInvokeHandler(context, deps) {
|
|
|
3540
3447
|
deps.log.debug?.("feedback handling disabled");
|
|
3541
3448
|
return true;
|
|
3542
3449
|
}
|
|
3543
|
-
if (!await
|
|
3450
|
+
if (!await isMSTeamsInvokeAuthorized({
|
|
3451
|
+
context,
|
|
3452
|
+
deps,
|
|
3453
|
+
invokeKind: "feedback"
|
|
3454
|
+
})) return true;
|
|
3544
3455
|
let userComment;
|
|
3545
3456
|
if (value.actionValue?.feedback) try {
|
|
3546
3457
|
userComment = JSON.parse(value.actionValue.feedback).feedbackText || void 0;
|
|
@@ -3567,14 +3478,17 @@ async function runMSTeamsFeedbackInvokeHandler(context, deps) {
|
|
|
3567
3478
|
threadId: feedbackThreadId,
|
|
3568
3479
|
parentSessionKey: route.sessionKey
|
|
3569
3480
|
}).sessionKey;
|
|
3570
|
-
const feedbackEvent =
|
|
3481
|
+
const feedbackEvent = {
|
|
3482
|
+
type: "custom",
|
|
3483
|
+
event: "feedback",
|
|
3484
|
+
ts: Date.now(),
|
|
3571
3485
|
messageId,
|
|
3572
3486
|
value: isNegative ? "negative" : "positive",
|
|
3573
3487
|
comment: userComment,
|
|
3574
3488
|
sessionKey: route.sessionKey,
|
|
3575
3489
|
agentId: route.agentId,
|
|
3576
3490
|
conversationId
|
|
3577
|
-
}
|
|
3491
|
+
};
|
|
3578
3492
|
deps.log.info("received feedback", {
|
|
3579
3493
|
value: feedbackEvent.value,
|
|
3580
3494
|
messageId,
|
|
@@ -3860,15 +3774,9 @@ function createMSTeamsIngress(options) {
|
|
|
3860
3774
|
stop: () => {
|
|
3861
3775
|
stopTask ??= (async () => {
|
|
3862
3776
|
await monitor.pause();
|
|
3863
|
-
let graceTimer;
|
|
3864
|
-
const graceElapsed = new Promise((resolve) => {
|
|
3865
|
-
graceTimer = setTimeout(resolve, require_resolve_allowlist.MSTEAMS_REQUEST_TIMEOUT_MS);
|
|
3866
|
-
graceTimer.unref?.();
|
|
3867
|
-
});
|
|
3868
3777
|
try {
|
|
3869
|
-
await
|
|
3778
|
+
await (0, openclaw_plugin_sdk_time_runtime.raceWithTimeout)(() => monitor.waitForIdle(), require_resolve_allowlist.MSTEAMS_REQUEST_TIMEOUT_MS, () => void 0, { ref: false });
|
|
3870
3779
|
} finally {
|
|
3871
|
-
clearTimeout(graceTimer);
|
|
3872
3780
|
await monitor.stop();
|
|
3873
3781
|
liveContexts.clear();
|
|
3874
3782
|
}
|
|
@@ -3933,11 +3841,6 @@ function createMSTeamsReplayContext(activity, app, serviceUrlBoundary) {
|
|
|
3933
3841
|
* Tokens are keyed by (connectionName, userId). `userId` should be the
|
|
3934
3842
|
* stable AAD object ID (`activity.from.aadObjectId`) when available,
|
|
3935
3843
|
* falling back to the Bot Framework `activity.from.id`.
|
|
3936
|
-
*
|
|
3937
|
-
* The store is intentionally minimal: it persists the exchanged user
|
|
3938
|
-
* token plus its expiration so consumers (for example tool handlers
|
|
3939
|
-
* that call Microsoft Graph with delegated permissions) can fetch a
|
|
3940
|
-
* valid token without reaching back into Bot Framework every turn.
|
|
3941
3844
|
*/
|
|
3942
3845
|
const MSTEAMS_SSO_TOKENS_NAMESPACE = "sso-tokens";
|
|
3943
3846
|
const SSO_TOKEN_MUTATION_KEY = "sso-tokens";
|
|
@@ -3946,15 +3849,12 @@ const STORE_KEY_VERSION_PREFIX = "v2:";
|
|
|
3946
3849
|
function makeMSTeamsSsoTokenStoreKey(connectionName, userId) {
|
|
3947
3850
|
return `${STORE_KEY_VERSION_PREFIX}${(0, node_crypto.createHash)("sha256").update(JSON.stringify([connectionName, userId])).digest("hex")}`;
|
|
3948
3851
|
}
|
|
3949
|
-
function
|
|
3950
|
-
|
|
3852
|
+
function createMSTeamsSsoTokenStoreFs(params) {
|
|
3853
|
+
const tokenStore = require_runtime.getMSTeamsRuntime().state.openKeyedStore({
|
|
3951
3854
|
namespace: MSTEAMS_SSO_TOKENS_NAMESPACE,
|
|
3952
3855
|
maxEntries: MSTEAMS_MAX_SSO_TOKENS,
|
|
3953
3856
|
env: require_conversation_store_state.resolveMSTeamsSqliteStateEnv(params)
|
|
3954
3857
|
});
|
|
3955
|
-
}
|
|
3956
|
-
function createMSTeamsSsoTokenStoreFs(params) {
|
|
3957
|
-
const tokenStore = createTokenStore(params);
|
|
3958
3858
|
return {
|
|
3959
3859
|
async get({ connectionName, userId }) {
|
|
3960
3860
|
return await tokenStore.lookup(makeMSTeamsSsoTokenStoreKey(connectionName, userId)) ?? null;
|
|
@@ -3965,11 +3865,7 @@ function createMSTeamsSsoTokenStoreFs(params) {
|
|
|
3965
3865
|
});
|
|
3966
3866
|
},
|
|
3967
3867
|
async remove({ connectionName, userId }) {
|
|
3968
|
-
|
|
3969
|
-
await require_conversation_store_state.withMSTeamsSqliteMutationLock(params, SSO_TOKEN_MUTATION_KEY, async () => {
|
|
3970
|
-
removed = await tokenStore.delete(makeMSTeamsSsoTokenStoreKey(connectionName, userId));
|
|
3971
|
-
});
|
|
3972
|
-
return removed;
|
|
3868
|
+
return require_conversation_store_state.withMSTeamsSqliteMutationLock(params, SSO_TOKEN_MUTATION_KEY, () => tokenStore.delete(makeMSTeamsSsoTokenStoreKey(connectionName, userId)));
|
|
3973
3869
|
}
|
|
3974
3870
|
};
|
|
3975
3871
|
}
|
|
@@ -4035,7 +3931,7 @@ async function monitorMSTeamsProvider(opts) {
|
|
|
4035
3931
|
shutdown: async () => {}
|
|
4036
3932
|
};
|
|
4037
3933
|
}
|
|
4038
|
-
const creds =
|
|
3934
|
+
const creds = require_token_config.resolveMSTeamsCredentials(msteamsCfg);
|
|
4039
3935
|
if (!creds) {
|
|
4040
3936
|
log.error("msteams credentials not configured");
|
|
4041
3937
|
publishMSTeamsBlocked(opts.statusSink, "Microsoft Teams credentials are not configured");
|
|
@@ -4220,7 +4116,11 @@ async function monitorMSTeamsProvider(opts) {
|
|
|
4220
4116
|
if (vote) {
|
|
4221
4117
|
const voterId = activity?.from?.aadObjectId ?? activity?.from?.id ?? "unknown";
|
|
4222
4118
|
try {
|
|
4223
|
-
if (!await
|
|
4119
|
+
if (!await isMSTeamsInvokeAuthorized({
|
|
4120
|
+
context: adaptedCtx,
|
|
4121
|
+
deps: handlerDeps,
|
|
4122
|
+
invokeKind: "card action"
|
|
4123
|
+
})) return cardActionMessage("Not authorized.");
|
|
4224
4124
|
const existingPoll = await pollStore.getPoll(vote.pollId);
|
|
4225
4125
|
if (!existingPoll) {
|
|
4226
4126
|
log.debug?.("poll vote ignored (poll not found)", { pollId: vote.pollId });
|
|
@@ -4254,36 +4154,14 @@ async function monitorMSTeamsProvider(opts) {
|
|
|
4254
4154
|
pollId: vote.pollId,
|
|
4255
4155
|
error: require_channel_setup.formatUnknownError(err)
|
|
4256
4156
|
});
|
|
4257
|
-
return
|
|
4258
|
-
statusCode: 500,
|
|
4259
|
-
type: "application/vnd.microsoft.error",
|
|
4260
|
-
value: {
|
|
4261
|
-
code: "RECORD_VOTE_FAILED",
|
|
4262
|
-
message: "Could not record vote.",
|
|
4263
|
-
innerHttpError: {
|
|
4264
|
-
statusCode: 500,
|
|
4265
|
-
body: null
|
|
4266
|
-
}
|
|
4267
|
-
}
|
|
4268
|
-
};
|
|
4157
|
+
return cardActionError("RECORD_VOTE_FAILED", "Could not record vote.");
|
|
4269
4158
|
}
|
|
4270
4159
|
}
|
|
4271
4160
|
await ingress.accept(activity, adaptedCtx);
|
|
4272
4161
|
return cardActionMessage("OK");
|
|
4273
4162
|
} catch (err) {
|
|
4274
4163
|
log.error("msteams card.action failed", { error: require_channel_setup.formatUnknownError(err) });
|
|
4275
|
-
return
|
|
4276
|
-
statusCode: 500,
|
|
4277
|
-
type: "application/vnd.microsoft.error",
|
|
4278
|
-
value: {
|
|
4279
|
-
code: "CARD_ACTION_FAILED",
|
|
4280
|
-
message: "Card action failed.",
|
|
4281
|
-
innerHttpError: {
|
|
4282
|
-
statusCode: 500,
|
|
4283
|
-
body: null
|
|
4284
|
-
}
|
|
4285
|
-
}
|
|
4286
|
-
};
|
|
4164
|
+
return cardActionError("CARD_ACTION_FAILED", "Card action failed.");
|
|
4287
4165
|
}
|
|
4288
4166
|
});
|
|
4289
4167
|
app.on("file.consent.accept", (ctx) => {
|
|
@@ -4296,11 +4174,15 @@ async function monitorMSTeamsProvider(opts) {
|
|
|
4296
4174
|
app.process = async (event) => {
|
|
4297
4175
|
const activity = event.body;
|
|
4298
4176
|
if (activity.type !== "invoke" || !("name" in activity) || activity.name !== "signin/tokenExchange" && activity.name !== "signin/verifyState") return processActivity(event);
|
|
4299
|
-
if (!await
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4177
|
+
if (!await isMSTeamsInvokeAuthorized({
|
|
4178
|
+
context: { activity: {
|
|
4179
|
+
...activity,
|
|
4180
|
+
type: activity.type,
|
|
4181
|
+
name: activity.name
|
|
4182
|
+
} },
|
|
4183
|
+
deps: handlerDeps,
|
|
4184
|
+
invokeKind: "signin"
|
|
4185
|
+
})) return {
|
|
4304
4186
|
status: 200,
|
|
4305
4187
|
body: {}
|
|
4306
4188
|
};
|
|
@@ -4315,7 +4197,11 @@ async function monitorMSTeamsProvider(opts) {
|
|
|
4315
4197
|
};
|
|
4316
4198
|
if (ssoDeps) app.event("signin", (ctx) => {
|
|
4317
4199
|
(async () => {
|
|
4318
|
-
if (!await
|
|
4200
|
+
if (!await isMSTeamsInvokeAuthorized({
|
|
4201
|
+
context: adaptSdkContext(ctx, app),
|
|
4202
|
+
deps: handlerDeps,
|
|
4203
|
+
invokeKind: "signin"
|
|
4204
|
+
})) return;
|
|
4319
4205
|
const activity = ctx.activity;
|
|
4320
4206
|
const userIds = Array.from(new Set([activity.from?.id, activity.from?.aadObjectId].filter((id) => Boolean(id))));
|
|
4321
4207
|
const connectionName = ctx.token.connectionName || ssoDeps.connectionName;
|
|
@@ -4430,6 +4316,20 @@ function cardActionMessage(value) {
|
|
|
4430
4316
|
value
|
|
4431
4317
|
};
|
|
4432
4318
|
}
|
|
4319
|
+
function cardActionError(code, message) {
|
|
4320
|
+
return {
|
|
4321
|
+
statusCode: 500,
|
|
4322
|
+
type: "application/vnd.microsoft.error",
|
|
4323
|
+
value: {
|
|
4324
|
+
code,
|
|
4325
|
+
message,
|
|
4326
|
+
innerHttpError: {
|
|
4327
|
+
statusCode: 500,
|
|
4328
|
+
body: null
|
|
4329
|
+
}
|
|
4330
|
+
}
|
|
4331
|
+
};
|
|
4332
|
+
}
|
|
4433
4333
|
/**
|
|
4434
4334
|
* Adapt a new @microsoft/teams.apps SDK context to the MSTeamsTurnContext interface
|
|
4435
4335
|
* our handlers expect. The new SDK uses reply()/send() instead of sendActivity().
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
1
|
+
const require_resolve_allowlist = require("./resolve-allowlist-Ct9yxQUw.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");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_resolve_allowlist = require("./resolve-allowlist-
|
|
1
|
+
const require_resolve_allowlist = require("./resolve-allowlist-Ct9yxQUw.cjs");
|
|
2
2
|
//#region extensions/msteams/src/graph-thread.ts
|
|
3
3
|
/**
|
|
4
4
|
* Strip HTML tags from Teams message content, preserving @mention display names.
|