From da4f82503f3c80613ee7dd1da8e530b009da5468 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 15 Mar 2026 17:50:35 -0700 Subject: [PATCH] MSTeams: lazy-load runtime-heavy channel paths --- extensions/msteams/src/channel.runtime.ts | 4 +++ extensions/msteams/src/channel.ts | 32 +++++++++++++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 extensions/msteams/src/channel.runtime.ts diff --git a/extensions/msteams/src/channel.runtime.ts b/extensions/msteams/src/channel.runtime.ts new file mode 100644 index 00000000000..45a0147f46b --- /dev/null +++ b/extensions/msteams/src/channel.runtime.ts @@ -0,0 +1,4 @@ +export { listMSTeamsDirectoryGroupsLive, listMSTeamsDirectoryPeersLive } from "./directory-live.js"; +export { msteamsOutbound } from "./outbound.js"; +export { probeMSTeams } from "./probe.js"; +export { sendAdaptiveCardMSTeams, sendMessageMSTeams } from "./send.js"; diff --git a/extensions/msteams/src/channel.ts b/extensions/msteams/src/channel.ts index cc1eca50fcb..a5c8f0bbe58 100644 --- a/extensions/msteams/src/channel.ts +++ b/extensions/msteams/src/channel.ts @@ -16,11 +16,8 @@ import { MSTeamsConfigSchema, PAIRING_APPROVED_MESSAGE, } from "openclaw/plugin-sdk/msteams"; -import { listMSTeamsDirectoryGroupsLive, listMSTeamsDirectoryPeersLive } from "./directory-live.js"; import { msteamsOnboardingAdapter } from "./onboarding.js"; -import { msteamsOutbound } from "./outbound.js"; import { resolveMSTeamsGroupToolPolicy } from "./policy.js"; -import { probeMSTeams } from "./probe.js"; import { normalizeMSTeamsMessagingTarget, normalizeMSTeamsUserInput, @@ -29,7 +26,7 @@ import { resolveMSTeamsChannelAllowlist, resolveMSTeamsUserAllowlist, } from "./resolve-allowlist.js"; -import { sendAdaptiveCardMSTeams, sendMessageMSTeams } from "./send.js"; +import { getMSTeamsRuntime } from "./runtime.js"; import { resolveMSTeamsCredentials } from "./token.js"; type ResolvedMSTeamsAccount = { @@ -49,6 +46,10 @@ const meta = { order: 60, } as const; +async function loadMSTeamsChannelRuntime() { + return await import("./channel.runtime.js"); +} + export const msteamsPlugin: ChannelPlugin = { id: "msteams", meta: { @@ -60,6 +61,7 @@ export const msteamsPlugin: ChannelPlugin = { idLabel: "msteamsUserId", normalizeAllowEntry: (entry) => entry.replace(/^(msteams|user):/i, ""), notifyApproval: async ({ cfg, id }) => { + const { sendMessageMSTeams } = await loadMSTeamsChannelRuntime(); await sendMessageMSTeams({ cfg, to: id, @@ -233,9 +235,9 @@ export const msteamsPlugin: ChannelPlugin = { .map((id) => ({ kind: "group", id }) as const); }, listPeersLive: async ({ cfg, query, limit }) => - listMSTeamsDirectoryPeersLive({ cfg, query, limit }), + (await loadMSTeamsChannelRuntime()).listMSTeamsDirectoryPeersLive({ cfg, query, limit }), listGroupsLive: async ({ cfg, query, limit }) => - listMSTeamsDirectoryGroupsLive({ cfg, query, limit }), + (await loadMSTeamsChannelRuntime()).listMSTeamsDirectoryGroupsLive({ cfg, query, limit }), }, resolver: { resolveTargets: async ({ cfg, inputs, kind, runtime }) => { @@ -398,6 +400,7 @@ export const msteamsPlugin: ChannelPlugin = { details: { error: "Card send requires a target (to)." }, }; } + const { sendAdaptiveCardMSTeams } = await loadMSTeamsChannelRuntime(); const result = await sendAdaptiveCardMSTeams({ cfg: ctx.cfg, to, @@ -422,14 +425,27 @@ export const msteamsPlugin: ChannelPlugin = { return null as never; }, }, - outbound: msteamsOutbound, + outbound: { + deliveryMode: "direct", + chunker: (text, limit) => getMSTeamsRuntime().channel.text.chunkMarkdownText(text, limit), + chunkerMode: "markdown", + textChunkLimit: 4000, + pollMaxOptions: 12, + sendText: async (params) => + (await loadMSTeamsChannelRuntime()).msteamsOutbound.sendText!(params), + sendMedia: async (params) => + (await loadMSTeamsChannelRuntime()).msteamsOutbound.sendMedia!(params), + sendPoll: async (params) => + (await loadMSTeamsChannelRuntime()).msteamsOutbound.sendPoll!(params), + }, status: { defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID, { port: null }), buildChannelSummary: ({ snapshot }) => buildProbeChannelStatusSummary(snapshot, { port: snapshot.port ?? null, }), - probeAccount: async ({ cfg }) => await probeMSTeams(cfg.channels?.msteams), + probeAccount: async ({ cfg }) => + await (await loadMSTeamsChannelRuntime()).probeMSTeams(cfg.channels?.msteams), buildAccountSnapshot: ({ account, runtime, probe }) => ({ accountId: account.accountId, enabled: account.enabled,