refactor(shared): consolidate remaining channel lazy loaders (#99302)

This commit is contained in:
Dallin Romney
2026-07-02 19:08:11 -07:00
committed by GitHub
parent 3ad465d32b
commit 59b08b4693
45 changed files with 244 additions and 527 deletions
+7 -25
View File
@@ -2,42 +2,24 @@
import { rm } from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { definePluginEntry, type OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
import {
normalizeLowercaseStringOrEmpty,
normalizeOptionalString,
} from "openclaw/plugin-sdk/string-coerce-runtime";
import { buildDevicePairPairingQrChannelData } from "./pairing-qr-channel-data.js";
type DevicePairApiModule = typeof import("./api.js");
type NotifyModule = typeof import("./notify.js");
type PairCommandApproveModule = typeof import("./pair-command-approve.js");
type PairCommandAuthModule = typeof import("./pair-command-auth.js");
let devicePairApiModulePromise: Promise<DevicePairApiModule> | undefined;
let notifyModulePromise: Promise<NotifyModule> | undefined;
let pairCommandApproveModulePromise: Promise<PairCommandApproveModule> | undefined;
let pairCommandAuthModulePromise: Promise<PairCommandAuthModule> | undefined;
const loadDevicePairApiModule = createLazyRuntimeModule(() => import("./api.js"));
function loadDevicePairApiModule(): Promise<DevicePairApiModule> {
devicePairApiModulePromise ??= import("./api.js");
return devicePairApiModulePromise;
}
const loadNotifyModule = createLazyRuntimeModule(() => import("./notify.js"));
function loadNotifyModule(): Promise<NotifyModule> {
notifyModulePromise ??= import("./notify.js");
return notifyModulePromise;
}
const loadPairCommandApproveModule = createLazyRuntimeModule(
() => import("./pair-command-approve.js"),
);
function loadPairCommandApproveModule(): Promise<PairCommandApproveModule> {
pairCommandApproveModulePromise ??= import("./pair-command-approve.js");
return pairCommandApproveModulePromise;
}
function loadPairCommandAuthModule(): Promise<PairCommandAuthModule> {
pairCommandAuthModulePromise ??= import("./pair-command-auth.js");
return pairCommandAuthModulePromise;
}
const loadPairCommandAuthModule = createLazyRuntimeModule(() => import("./pair-command-auth.js"));
function formatDurationMinutes(expiresAtMs: number): string {
const msRemaining = Math.max(0, expiresAtMs - Date.now());
+2 -6
View File
@@ -1,3 +1,4 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Feishu plugin module implements monitor behavior.
import type { ClawdbotConfig, PluginRuntime, RuntimeEnv } from "../runtime-api.js";
import { listEnabledFeishuAccounts, resolveFeishuRuntimeAccount } from "./accounts.js";
@@ -40,12 +41,7 @@ export type FeishuStatusSink = (patch: {
lastError?: string | null;
}) => void;
let monitorAccountRuntimePromise: Promise<typeof import("./monitor.account.js")> | undefined;
async function loadMonitorAccountRuntime() {
monitorAccountRuntimePromise ??= import("./monitor.account.js");
return await monitorAccountRuntimePromise;
}
const loadMonitorAccountRuntime = createLazyRuntimeModule(() => import("./monitor.account.js"));
export {
clearFeishuWebhookRateLimitStateForTest,
+2 -10
View File
@@ -1,3 +1,4 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Feishu plugin module implements setup surface behavior.
import {
DEFAULT_ACCOUNT_ID,
@@ -248,16 +249,7 @@ function applyNewAppSecurityPolicy(
return next;
}
// ---------------------------------------------------------------------------
// Scan-to-create flow
// ---------------------------------------------------------------------------
let appRegistrationModulePromise: Promise<typeof import("./app-registration.js")> | null = null;
const loadAppRegistrationModule = async () => {
appRegistrationModulePromise ??= import("./app-registration.js");
return await appRegistrationModulePromise;
};
const loadAppRegistrationModule = createLazyRuntimeModule(() => import("./app-registration.js"));
async function promptFeishuDomain(params: {
prompter: WizardPrompter;
+4 -8
View File
@@ -1,14 +1,10 @@
// Feishu API module exposes the plugin public contract.
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/channel-entry-contract";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
type FeishuSubagentHooksModule = typeof import("./src/subagent-hooks.js");
let feishuSubagentHooksPromise: Promise<FeishuSubagentHooksModule> | null = null;
function loadFeishuSubagentHooksModule() {
feishuSubagentHooksPromise ??= import("./src/subagent-hooks.js");
return feishuSubagentHooksPromise;
}
const loadFeishuSubagentHooksModule = createLazyRuntimeModule(
() => import("./src/subagent-hooks.js"),
);
export function registerFeishuSubagentHooks(api: OpenClawPluginApi): void {
api.on("subagent_delivery_target", async (event) => {
+3 -11
View File
@@ -10,6 +10,7 @@ import {
errorShape,
type GatewayRequestHandlerOptions,
} from "openclaw/plugin-sdk/gateway-runtime";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { definePluginEntry, type OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry";
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
import { Type } from "typebox";
@@ -42,18 +43,9 @@ import {
import { GoogleMeetRuntime } from "./src/runtime.js";
import { isGoogleMeetBrowserManualActionError } from "./src/transports/chrome-create.js";
let googleMeetCreateModulePromise: Promise<typeof import("./src/create.js")> | null = null;
let googleMeetCliModulePromise: Promise<typeof import("./src/cli.js")> | null = null;
const loadGoogleMeetCreateModule = createLazyRuntimeModule(() => import("./src/create.js"));
const loadGoogleMeetCreateModule = async () => {
googleMeetCreateModulePromise ??= import("./src/create.js");
return await googleMeetCreateModulePromise;
};
const loadGoogleMeetCliModule = async () => {
googleMeetCliModulePromise ??= import("./src/cli.js");
return await googleMeetCliModulePromise;
};
const loadGoogleMeetCliModule = createLazyRuntimeModule(() => import("./src/cli.js"));
const googleMeetConfigSchema = {
parse(value: unknown) {
@@ -9,6 +9,7 @@ import {
} from "openclaw/plugin-sdk/approval-reaction-runtime";
import type { ExecApprovalReplyDecision } from "openclaw/plugin-sdk/approval-reply-runtime";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import {
asDateTimestampMs,
isFutureDateTimestampMs,
@@ -58,13 +59,10 @@ export type PendingIMessageApprovalReactionPollTarget = {
expiresAtMs: number;
};
let resolverRuntimePromise: Promise<typeof import("./approval-resolver.js")> | undefined;
const resolverRuntimeLoader = createLazyRuntimeModule(() => import("./approval-resolver.js"));
const pendingReactionPollTargets = new Map<string, PendingIMessageApprovalReactionPollTarget>();
function loadApprovalResolver(): Promise<typeof import("./approval-resolver.js")> {
resolverRuntimePromise ??= import("./approval-resolver.js");
return resolverRuntimePromise;
}
const loadApprovalResolver = resolverRuntimeLoader;
function chatIdToKeyValue(chatId: number | string | undefined): string | null {
if (chatId == null || chatId === "") {
@@ -639,5 +637,5 @@ export async function maybeResolveIMessageApprovalReaction(params: {
export function clearIMessageApprovalReactionTargetsForTest(): void {
imessageApprovalReactionTargets.clearForTest();
pendingReactionPollTargets.clear();
resolverRuntimePromise = undefined;
resolverRuntimeLoader.clear();
}
+2 -8
View File
@@ -15,6 +15,7 @@ import {
createChannelDirectoryAdapter,
createResolvedDirectoryEntriesLister,
} from "openclaw/plugin-sdk/directory-runtime";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import {
createComputedAccountStatusAdapter,
createDefaultChannelRuntimeState,
@@ -62,14 +63,7 @@ const meta = {
markdownCapable: true,
};
type IrcChannelRuntimeModule = typeof import("./channel-runtime.js");
let ircChannelRuntimePromise: Promise<IrcChannelRuntimeModule> | undefined;
async function loadIrcChannelRuntime(): Promise<IrcChannelRuntimeModule> {
ircChannelRuntimePromise ??= import("./channel-runtime.js");
return await ircChannelRuntimePromise;
}
const loadIrcChannelRuntime = createLazyRuntimeModule(() => import("./channel-runtime.js"));
function normalizePairingTarget(raw: string): string {
const normalized = normalizeIrcAllowEntry(raw);
+2 -8
View File
@@ -1,19 +1,13 @@
// Irc plugin module implements gateway behavior.
import { runStoppablePassiveMonitor } from "openclaw/plugin-sdk/extension-shared";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import type { ChannelAccountSnapshot } from "openclaw/plugin-sdk/status-helpers";
import type { ResolvedIrcAccount } from "./accounts.js";
import { createAccountStatusSink } from "./channel-api.js";
import type { RuntimeEnv } from "./runtime-api.js";
import type { CoreConfig } from "./types.js";
type IrcChannelRuntimeModule = typeof import("./channel-runtime.js");
let ircChannelRuntimePromise: Promise<IrcChannelRuntimeModule> | undefined;
async function loadIrcChannelRuntime(): Promise<IrcChannelRuntimeModule> {
ircChannelRuntimePromise ??= import("./channel-runtime.js");
return await ircChannelRuntimePromise;
}
const loadIrcChannelRuntime = createLazyRuntimeModule(() => import("./channel-runtime.js"));
export async function startIrcGatewayAccount(ctx: {
cfg: CoreConfig;
+6 -7
View File
@@ -4,13 +4,12 @@ import {
type OpenClawPluginCommandDefinition,
type OpenClawPluginApi,
} from "openclaw/plugin-sdk/channel-entry-contract";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
type RegisteredLineCardCommand = OpenClawPluginCommandDefinition;
let lineCardCommandPromise: Promise<RegisteredLineCardCommand> | null = null;
async function loadLineCardCommand(api: OpenClawPluginApi): Promise<RegisteredLineCardCommand> {
lineCardCommandPromise ??= (async () => {
function createLineCardCommandLoader(api: OpenClawPluginApi) {
return createLazyRuntimeModule<RegisteredLineCardCommand>(async () => {
let registered: RegisteredLineCardCommand | null = null;
const { registerLineCardCommand } = await import("./src/card-command.js");
registerLineCardCommand({
@@ -23,8 +22,7 @@ async function loadLineCardCommand(api: OpenClawPluginApi): Promise<RegisteredLi
throw new Error("LINE card command registration unavailable");
}
return registered;
})();
return await lineCardCommandPromise;
});
}
export default defineBundledChannelEntry({
@@ -41,13 +39,14 @@ export default defineBundledChannelEntry({
exportName: "setLineRuntime",
},
registerFull(api) {
const loadLineCardCommand = createLineCardCommandLoader(api);
api.registerCommand({
name: "card",
description: "Send a rich card message (LINE).",
acceptsArgs: true,
requireAuth: false,
async handler(ctx) {
const command = await loadLineCardCommand(api);
const command = await loadLineCardCommand();
return await command.handler(ctx);
},
});
+4 -8
View File
@@ -3,17 +3,13 @@ import {
defineBundledChannelEntry,
type OpenClawPluginApi,
} from "openclaw/plugin-sdk/channel-entry-contract";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { registerMatrixCliMetadata } from "./cli-metadata.js";
import { registerMatrixSubagentHooks } from "./subagent-hooks-api.js";
type MatrixHandlersRuntimeModule = typeof import("./plugin-entry.handlers.runtime.js");
let matrixHandlersRuntimePromise: Promise<MatrixHandlersRuntimeModule> | null = null;
function loadMatrixHandlersRuntimeModule() {
matrixHandlersRuntimePromise ??= import("./plugin-entry.handlers.runtime.js");
return matrixHandlersRuntimePromise;
}
const loadMatrixHandlersRuntimeModule = createLazyRuntimeModule(
() => import("./plugin-entry.handlers.runtime.js"),
);
export function registerMatrixFullRuntime(api: OpenClawPluginApi): void {
api.registerGatewayMethod("matrix.verify.recoveryKey", async (ctx) => {
+5 -6
View File
@@ -21,7 +21,10 @@ import {
createResolvedDirectoryEntriesLister,
createRuntimeDirectoryLiveAdapter,
} from "openclaw/plugin-sdk/directory-runtime";
import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
import {
createLazyRuntimeNamedExport,
createLazyRuntimeModule,
} from "openclaw/plugin-sdk/lazy-runtime";
import {
buildProbeChannelStatusSummary,
collectStatusIssuesFromLastError,
@@ -89,12 +92,8 @@ const loadMatrixChannelRuntime = createLazyRuntimeNamedExport(
() => import("./channel.runtime.js"),
"matrixChannelRuntime",
);
let matrixDoctorModulePromise: Promise<typeof import("./doctor.js")> | null = null;
const loadMatrixDoctorModule = async () => {
matrixDoctorModulePromise ??= import("./doctor.js");
return await matrixDoctorModulePromise;
};
const loadMatrixDoctorModule = createLazyRuntimeModule(() => import("./doctor.js"));
const meta = {
id: "matrix",
+7 -13
View File
@@ -1,6 +1,7 @@
// Matrix plugin module implements cli behavior.
import type { Command } from "commander";
import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { parseStrictInteger, timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
import type { ChannelSetupInput } from "openclaw/plugin-sdk/setup";
import { resolveMatrixAccount, resolveMatrixAccountConfig } from "./matrix/accounts.js";
@@ -37,21 +38,14 @@ import { matrixSetupAdapter } from "./setup-core.js";
import type { CoreConfig } from "./types.js";
let matrixCliExitScheduled = false;
type MatrixActionClientModule = typeof import("./matrix/actions/client.js");
type MatrixDirectManagementModule = typeof import("./matrix/direct-management.js");
let matrixActionClientModulePromise: Promise<MatrixActionClientModule> | undefined;
let matrixDirectManagementModulePromise: Promise<MatrixDirectManagementModule> | undefined;
const loadMatrixActionClientModule = createLazyRuntimeModule(
() => import("./matrix/actions/client.js"),
);
function loadMatrixActionClientModule(): Promise<MatrixActionClientModule> {
matrixActionClientModulePromise ??= import("./matrix/actions/client.js");
return matrixActionClientModulePromise;
}
function loadMatrixDirectManagementModule(): Promise<MatrixDirectManagementModule> {
matrixDirectManagementModulePromise ??= import("./matrix/direct-management.js");
return matrixDirectManagementModulePromise;
}
const loadMatrixDirectManagementModule = createLazyRuntimeModule(
() => import("./matrix/direct-management.js"),
);
export function resetMatrixCliStateForTests(): void {
matrixCliExitScheduled = false;
@@ -1,3 +1,4 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Matrix plugin module implements client bootstrap behavior.
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
import type { CoreConfig } from "../types.js";
@@ -19,25 +20,15 @@ type MatrixResolvedClientHook = (
context: { preparedByDefault: boolean },
) => Promise<void> | void;
type MatrixSharedClientRuntimeDeps = Pick<
typeof import("./client.js"),
"acquireSharedMatrixClient" | "resolveMatrixAuthContext"
> &
Pick<typeof import("./client/shared.js"), "releaseSharedClientInstance">;
let matrixSharedClientRuntimeDepsPromise: Promise<MatrixSharedClientRuntimeDeps> | undefined;
async function loadMatrixSharedClientRuntimeDeps(): Promise<MatrixSharedClientRuntimeDeps> {
matrixSharedClientRuntimeDepsPromise ??= Promise.all([
import("./client.js"),
import("./client/shared.js"),
]).then(([clientModule, sharedModule]) => ({
acquireSharedMatrixClient: clientModule.acquireSharedMatrixClient,
resolveMatrixAuthContext: clientModule.resolveMatrixAuthContext,
releaseSharedClientInstance: sharedModule.releaseSharedClientInstance,
}));
return await matrixSharedClientRuntimeDepsPromise;
}
const loadMatrixSharedClientRuntimeDeps = createLazyRuntimeModule(() =>
Promise.all([import("./client.js"), import("./client/shared.js")]).then(
([clientModule, sharedModule]) => ({
acquireSharedMatrixClient: clientModule.acquireSharedMatrixClient,
resolveMatrixAuthContext: clientModule.resolveMatrixAuthContext,
releaseSharedClientInstance: sharedModule.releaseSharedClientInstance,
}),
),
);
async function ensureResolvedClientReadiness(params: {
client: MatrixClient;
+21 -40
View File
@@ -1,5 +1,6 @@
// Matrix helper module supports config behavior.
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { resolveOptionalIntegerOption } from "openclaw/plugin-sdk/number-runtime";
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
import { retryAsync } from "openclaw/plugin-sdk/retry-runtime";
@@ -40,21 +41,12 @@ type MatrixAuthClientDeps = {
retryMinDelayMs?: number;
};
type MatrixCredentialsReadDeps = {
loadMatrixCredentials: typeof import("../credentials-read.js").loadMatrixCredentials;
credentialsMatchConfig: typeof import("../credentials-read.js").credentialsMatchConfig;
};
type MatrixCredentialsWriteRuntime = typeof import("../credentials-write.runtime.js");
type MatrixSecretInputDeps = {
resolveConfiguredSecretInputString: typeof import("./config-secret-input.runtime.js").resolveConfiguredSecretInputString;
};
let matrixAuthClientDepsPromise: Promise<MatrixAuthClientDeps> | undefined;
let matrixCredentialsReadDepsPromise: Promise<MatrixCredentialsReadDeps> | undefined;
let matrixCredentialsWriteRuntimePromise: Promise<MatrixCredentialsWriteRuntime> | undefined;
let matrixSecretInputDepsPromise: Promise<MatrixSecretInputDeps> | undefined;
const loadDefaultMatrixAuthClientDeps = createLazyRuntimeModule(() =>
Promise.all([import("../sdk.js"), import("./logging.js")]).then(([sdkModule, loggingModule]) => ({
MatrixClient: sdkModule.MatrixClient,
ensureMatrixSdkLoggingConfigured: loggingModule.ensureMatrixSdkLoggingConfigured,
})),
);
let matrixAuthClientDepsForTest: MatrixAuthClientDeps | undefined;
const MATRIX_AUTH_REQUEST_RETRY_RE =
@@ -72,36 +64,25 @@ async function loadMatrixAuthClientDeps(): Promise<MatrixAuthClientDeps> {
if (matrixAuthClientDepsForTest) {
return matrixAuthClientDepsForTest;
}
matrixAuthClientDepsPromise ??= Promise.all([import("../sdk.js"), import("./logging.js")]).then(
([sdkModule, loggingModule]) => ({
MatrixClient: sdkModule.MatrixClient,
ensureMatrixSdkLoggingConfigured: loggingModule.ensureMatrixSdkLoggingConfigured,
}),
);
return await matrixAuthClientDepsPromise;
return await loadDefaultMatrixAuthClientDeps();
}
async function loadMatrixCredentialsReadDeps(): Promise<MatrixCredentialsReadDeps> {
matrixCredentialsReadDepsPromise ??= import("../credentials-read.js").then(
(credentialsReadModule) => ({
loadMatrixCredentials: credentialsReadModule.loadMatrixCredentials,
credentialsMatchConfig: credentialsReadModule.credentialsMatchConfig,
}),
);
return await matrixCredentialsReadDepsPromise;
}
const loadMatrixCredentialsReadDeps = createLazyRuntimeModule(() =>
import("../credentials-read.js").then((credentialsReadModule) => ({
loadMatrixCredentials: credentialsReadModule.loadMatrixCredentials,
credentialsMatchConfig: credentialsReadModule.credentialsMatchConfig,
})),
);
async function loadMatrixCredentialsWriteRuntime(): Promise<MatrixCredentialsWriteRuntime> {
matrixCredentialsWriteRuntimePromise ??= import("../credentials-write.runtime.js");
return await matrixCredentialsWriteRuntimePromise;
}
const loadMatrixCredentialsWriteRuntime = createLazyRuntimeModule(
() => import("../credentials-write.runtime.js"),
);
async function loadMatrixSecretInputDeps(): Promise<MatrixSecretInputDeps> {
matrixSecretInputDepsPromise ??= import("./config-secret-input.runtime.js").then((runtime) => ({
const loadMatrixSecretInputDeps = createLazyRuntimeModule(() =>
import("./config-secret-input.runtime.js").then((runtime) => ({
resolveConfiguredSecretInputString: runtime.resolveConfiguredSecretInputString,
}));
return await matrixSecretInputDepsPromise;
}
})),
);
function shouldRetryMatrixAuthRequest(err: unknown): boolean {
return MATRIX_AUTH_REQUEST_RETRY_RE.test(formatErrorMessage(err));
@@ -1,5 +1,6 @@
// Matrix plugin module implements create client behavior.
import fs from "node:fs";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import type { PinnedDispatcherPolicy } from "openclaw/plugin-sdk/ssrf-dispatcher";
import {
ssrfPolicyFromDangerouslyAllowPrivateNetwork,
@@ -14,23 +15,12 @@ import {
writeStorageMeta,
} from "./storage.js";
type MatrixCreateClientRuntimeDeps = {
MatrixClient: typeof import("../sdk.js").MatrixClient;
ensureMatrixSdkLoggingConfigured: typeof import("./logging.js").ensureMatrixSdkLoggingConfigured;
};
let matrixCreateClientRuntimeDepsPromise: Promise<MatrixCreateClientRuntimeDeps> | undefined;
async function loadMatrixCreateClientRuntimeDeps(): Promise<MatrixCreateClientRuntimeDeps> {
matrixCreateClientRuntimeDepsPromise ??= Promise.all([
import("../sdk.js"),
import("./logging.js"),
]).then(([sdkModule, loggingModule]) => ({
const loadMatrixCreateClientRuntimeDeps = createLazyRuntimeModule(() =>
Promise.all([import("../sdk.js"), import("./logging.js")]).then(([sdkModule, loggingModule]) => ({
MatrixClient: sdkModule.MatrixClient,
ensureMatrixSdkLoggingConfigured: loggingModule.ensureMatrixSdkLoggingConfigured,
}));
return await matrixCreateClientRuntimeDepsPromise;
}
})),
);
export async function createMatrixClient(params: {
homeserver: string;
+5 -11
View File
@@ -1,5 +1,6 @@
// Matrix plugin module implements shared behavior.
import { normalizeOptionalAccountId } from "openclaw/plugin-sdk/account-id";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import type { CoreConfig } from "../../types.js";
import type { MatrixClient } from "../sdk.js";
import { LogService } from "../sdk/logger.js";
@@ -7,18 +8,11 @@ import { awaitMatrixStartupWithAbort } from "../startup-abort.js";
import { resolveMatrixAuth, resolveMatrixAuthContext } from "./config.js";
import type { MatrixAuth } from "./types.js";
type MatrixCreateClientDeps = {
createMatrixClient: typeof import("./create-client.js").createMatrixClient;
};
let matrixCreateClientDepsPromise: Promise<MatrixCreateClientDeps> | undefined;
async function loadMatrixCreateClientDeps(): Promise<MatrixCreateClientDeps> {
matrixCreateClientDepsPromise ??= import("./create-client.js").then((runtime) => ({
const loadMatrixCreateClientDeps = createLazyRuntimeModule(() =>
import("./create-client.js").then((runtime) => ({
createMatrixClient: runtime.createMatrixClient,
}));
return await matrixCreateClientDepsPromise;
}
})),
);
type SharedMatrixClientState = {
client: MatrixClient;
@@ -1,3 +1,4 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Matrix plugin module implements credentials write behavior.
import type {
saveBackfilledMatrixDeviceId as saveBackfilledMatrixDeviceIdType,
@@ -5,14 +6,7 @@ import type {
touchMatrixCredentials as touchMatrixCredentialsType,
} from "./credentials.js";
type MatrixCredentialsRuntime = typeof import("./credentials.js");
let matrixCredentialsRuntimePromise: Promise<MatrixCredentialsRuntime> | undefined;
function loadMatrixCredentialsRuntime(): Promise<MatrixCredentialsRuntime> {
matrixCredentialsRuntimePromise ??= import("./credentials.js");
return matrixCredentialsRuntimePromise;
}
const loadMatrixCredentialsRuntime = createLazyRuntimeModule(() => import("./credentials.js"));
export async function saveMatrixCredentials(
...args: Parameters<typeof saveMatrixCredentialsType>
+10 -33
View File
@@ -27,6 +27,7 @@ import {
resolveChannelContextVisibilityMode,
} from "openclaw/plugin-sdk/context-visibility-runtime";
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import {
isFutureDateTimestampMs,
resolveExpiresAtMsFromDurationMs,
@@ -124,44 +125,20 @@ import { isMatrixVerificationRoomMessage } from "./verification-utils.js";
const ALLOW_FROM_STORE_CACHE_TTL_MS = 30_000;
const PAIRING_REPLY_COOLDOWN_MS = 5 * 60_000;
const MATRIX_TOOL_PROGRESS_MAX_CHARS = 300;
let matrixSendModulePromise: Promise<typeof import("../send.js")> | undefined;
let acpBindingRuntimePromise:
| Promise<typeof import("openclaw/plugin-sdk/acp-binding-runtime")>
| undefined;
let sessionBindingRuntimePromise:
| Promise<typeof import("openclaw/plugin-sdk/session-binding-runtime")>
| undefined;
let matrixReactionEventsPromise: Promise<typeof import("./reaction-events.js")> | undefined;
let matrixDraftStreamPromise: Promise<typeof import("../draft-stream.js")> | undefined;
function loadMatrixSendModule(): Promise<typeof import("../send.js")> {
matrixSendModulePromise ??= import("../send.js");
return matrixSendModulePromise;
}
const loadMatrixSendModule = createLazyRuntimeModule(() => import("../send.js"));
function loadAcpBindingRuntime(): Promise<
typeof import("openclaw/plugin-sdk/acp-binding-runtime")
> {
acpBindingRuntimePromise ??= import("openclaw/plugin-sdk/acp-binding-runtime");
return acpBindingRuntimePromise;
}
const loadAcpBindingRuntime = createLazyRuntimeModule(
() => import("openclaw/plugin-sdk/acp-binding-runtime"),
);
function loadSessionBindingRuntime(): Promise<
typeof import("openclaw/plugin-sdk/session-binding-runtime")
> {
sessionBindingRuntimePromise ??= import("openclaw/plugin-sdk/session-binding-runtime");
return sessionBindingRuntimePromise;
}
const loadSessionBindingRuntime = createLazyRuntimeModule(
() => import("openclaw/plugin-sdk/session-binding-runtime"),
);
function loadMatrixReactionEvents(): Promise<typeof import("./reaction-events.js")> {
matrixReactionEventsPromise ??= import("./reaction-events.js");
return matrixReactionEventsPromise;
}
const loadMatrixReactionEvents = createLazyRuntimeModule(() => import("./reaction-events.js"));
function loadMatrixDraftStream(): Promise<typeof import("../draft-stream.js")> {
matrixDraftStreamPromise ??= import("../draft-stream.js");
return matrixDraftStreamPromise;
}
const loadMatrixDraftStream = createLazyRuntimeModule(() => import("../draft-stream.js"));
async function matrixTextWouldActivateMentions(
client: MatrixClient,
@@ -1,15 +1,11 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
type MatrixPreflightAudioRuntime = typeof import("./preflight-audio.runtime.js");
const MATRIX_DEFAULT_ECHO_TRANSCRIPT_FORMAT = '📝 "{transcript}"';
let matrixPreflightAudioRuntimePromise: Promise<MatrixPreflightAudioRuntime> | undefined;
function loadMatrixPreflightAudioRuntime(): Promise<MatrixPreflightAudioRuntime> {
matrixPreflightAudioRuntimePromise ??= import("./preflight-audio.runtime.js");
return matrixPreflightAudioRuntimePromise;
}
const loadMatrixPreflightAudioRuntime = createLazyRuntimeModule(
() => import("./preflight-audio.runtime.js"),
);
export function formatMatrixAudioTranscript(transcript: string): string {
return `[Audio transcript (machine-generated, untrusted)]: ${JSON.stringify(transcript)}`;
@@ -1,3 +1,4 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Matrix plugin module implements reaction events behavior.
import { getSessionBindingService } from "openclaw/plugin-sdk/session-binding-runtime";
import {
@@ -13,22 +14,13 @@ import type { PluginRuntime } from "./runtime-api.js";
import { resolveMatrixThreadRootId, resolveMatrixThreadRouting } from "./threads.js";
import type { MatrixRawEvent, RoomMessageEventContent } from "./types.js";
let approvalReactionAuthPromise:
| Promise<typeof import("../../approval-reaction-auth.js")>
| undefined;
let execApprovalResolverPromise:
| Promise<typeof import("../../exec-approval-resolver.js")>
| undefined;
const loadApprovalReactionAuth = createLazyRuntimeModule(
() => import("../../approval-reaction-auth.js"),
);
function loadApprovalReactionAuth(): Promise<typeof import("../../approval-reaction-auth.js")> {
approvalReactionAuthPromise ??= import("../../approval-reaction-auth.js");
return approvalReactionAuthPromise;
}
function loadExecApprovalResolver(): Promise<typeof import("../../exec-approval-resolver.js")> {
execApprovalResolverPromise ??= import("../../exec-approval-resolver.js");
return execApprovalResolverPromise;
}
const loadExecApprovalResolver = createLazyRuntimeModule(
() => import("../../exec-approval-resolver.js"),
);
export type MatrixReactionNotificationMode = "off" | "own";
@@ -1,3 +1,4 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Matrix plugin module implements startup behavior.
import type { RuntimeLogger } from "../../runtime-api.js";
import type { CoreConfig, MatrixConfig } from "../../types.js";
@@ -25,10 +26,8 @@ export type MatrixStartupMaintenanceDeps = {
ensureMatrixStartupVerification: typeof import("./startup-verification.js").ensureMatrixStartupVerification;
};
let matrixStartupMaintenanceDepsPromise: Promise<MatrixStartupMaintenanceDeps> | undefined;
async function loadMatrixStartupMaintenanceDeps(): Promise<MatrixStartupMaintenanceDeps> {
matrixStartupMaintenanceDepsPromise ??= Promise.all([
const loadMatrixStartupMaintenanceDeps = createLazyRuntimeModule(() =>
Promise.all([
import("../config-update.js"),
import("../device-health.js"),
import("../profile.js"),
@@ -48,9 +47,8 @@ async function loadMatrixStartupMaintenanceDeps(): Promise<MatrixStartupMaintena
maybeRestoreLegacyMatrixBackup: legacyCryptoRestoreModule.maybeRestoreLegacyMatrixBackup,
ensureMatrixStartupVerification: startupVerificationModule.ensureMatrixStartupVerification,
}),
);
return await matrixStartupMaintenanceDepsPromise;
}
),
);
export async function runMatrixStartupMaintenance(
params: {
@@ -1,3 +1,4 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Matrix plugin module implements verification events behavior.
import type { MatrixClient } from "../sdk.js";
import { resolveMatrixMonitorAccessState } from "./access-state.js";
@@ -31,23 +32,14 @@ type MatrixVerificationSummaryLike = {
};
};
type MatrixDirectRoomDeps = {
inspectMatrixDirectRooms: typeof import("../direct-management.js").inspectMatrixDirectRooms;
isStrictDirectRoom: typeof import("../direct-room.js").isStrictDirectRoom;
};
let matrixDirectRoomDepsPromise: Promise<MatrixDirectRoomDeps> | undefined;
async function loadMatrixDirectRoomDeps(): Promise<MatrixDirectRoomDeps> {
matrixDirectRoomDepsPromise ??= Promise.all([
import("../direct-management.js"),
import("../direct-room.js"),
]).then(([directManagementModule, directRoomModule]) => ({
inspectMatrixDirectRooms: directManagementModule.inspectMatrixDirectRooms,
isStrictDirectRoom: directRoomModule.isStrictDirectRoom,
}));
return await matrixDirectRoomDepsPromise;
}
const loadMatrixDirectRoomDeps = createLazyRuntimeModule(() =>
Promise.all([import("../direct-management.js"), import("../direct-room.js")]).then(
([directManagementModule, directRoomModule]) => ({
inspectMatrixDirectRooms: directManagementModule.inspectMatrixDirectRooms,
isStrictDirectRoom: directRoomModule.isStrictDirectRoom,
}),
),
);
function trimMaybeString(input: unknown): string | null {
if (typeof input !== "string") {
+5 -9
View File
@@ -1,21 +1,17 @@
// Matrix plugin module implements probe behavior.
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import type { PinnedDispatcherPolicy } from "openclaw/plugin-sdk/ssrf-dispatcher";
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
import type { SsrFPolicy } from "../runtime-api.js";
import type { BaseProbeResult } from "../runtime-api.js";
import { isBunRuntime } from "./client/runtime.js";
type MatrixProbeRuntimeDeps = Pick<typeof import("./probe.runtime.js"), "createMatrixClient">;
let matrixProbeRuntimeDepsPromise: Promise<MatrixProbeRuntimeDeps> | undefined;
async function loadMatrixProbeRuntimeDeps(): Promise<MatrixProbeRuntimeDeps> {
matrixProbeRuntimeDepsPromise ??= import("./probe.runtime.js").then((runtimeModule) => ({
const loadMatrixProbeRuntimeDeps = createLazyRuntimeModule(() =>
import("./probe.runtime.js").then((runtimeModule) => ({
createMatrixClient: runtimeModule.createMatrixClient,
}));
return await matrixProbeRuntimeDepsPromise;
}
})),
);
export type MatrixProbe = BaseProbeResult & {
status?: number | null;
+5 -6
View File
@@ -13,6 +13,7 @@ import {
import type { Direction } from "matrix-js-sdk/lib/models/event-timeline.js";
import { VerificationMethod } from "matrix-js-sdk/lib/types.js";
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import type { PinnedDispatcherPolicy } from "openclaw/plugin-sdk/ssrf-dispatcher";
import {
normalizeNullableString,
@@ -294,15 +295,13 @@ export type MatrixOwnDeviceDeleteResult = {
type MatrixCryptoRuntime = typeof import("./sdk/crypto-runtime.js");
let loadedMatrixCryptoRuntime: MatrixCryptoRuntime | null = null;
let matrixCryptoRuntimePromise: Promise<MatrixCryptoRuntime> | null = null;
async function loadMatrixCryptoRuntime(): Promise<MatrixCryptoRuntime> {
matrixCryptoRuntimePromise ??= import("./sdk/crypto-runtime.js").then((runtime) => {
const loadMatrixCryptoRuntime = createLazyRuntimeModule(() =>
import("./sdk/crypto-runtime.js").then((runtime) => {
loadedMatrixCryptoRuntime = runtime;
return runtime;
});
return await matrixCryptoRuntimePromise;
}
}),
);
const normalizeOptionalString = normalizeNullableString;
@@ -1,4 +1,5 @@
// Matrix plugin module implements crypto facade behavior.
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { ensureMatrixCryptoRuntime } from "../deps.js";
import type { MatrixRecoveryKeyStore } from "./recovery-key-store.js";
import type { EncryptedFile } from "./types.js";
@@ -67,15 +68,18 @@ export type MatrixCryptoFacade = {
};
type MatrixCryptoNodeRuntime = typeof import("./crypto-node.runtime.js");
let matrixCryptoNodeRuntimePromise: Promise<MatrixCryptoNodeRuntime> | null = null;
const matrixCryptoNodeRuntimeLoader = createLazyRuntimeModule(
() => import("./crypto-node.runtime.js"),
);
async function loadMatrixCryptoNodeRuntime(): Promise<MatrixCryptoNodeRuntime> {
// Keep the native crypto package out of the main CLI startup graph.
matrixCryptoNodeRuntimePromise ??= import("./crypto-node.runtime.js").catch((error: unknown) => {
matrixCryptoNodeRuntimePromise = null;
try {
return await matrixCryptoNodeRuntimeLoader();
} catch (error) {
matrixCryptoNodeRuntimeLoader.clear();
throw error;
});
return await matrixCryptoNodeRuntimePromise;
}
}
async function loadMatrixCryptoNodeBindings() {
+2 -11
View File
@@ -1,20 +1,11 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Matrix plugin module implements client behavior.
import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";
import type { CoreConfig } from "../../types.js";
import { resolveMatrixAccountConfig } from "../account-config.js";
import type { MatrixClient } from "../sdk.js";
type MatrixSendClientRuntime = Pick<
typeof import("../client-bootstrap.js"),
"withResolvedRuntimeMatrixClient"
>;
let matrixSendClientRuntimePromise: Promise<MatrixSendClientRuntime> | null = null;
async function loadMatrixSendClientRuntime(): Promise<MatrixSendClientRuntime> {
matrixSendClientRuntimePromise ??= import("../client-bootstrap.js");
return await matrixSendClientRuntimePromise;
}
const loadMatrixSendClientRuntime = createLazyRuntimeModule(() => import("../client-bootstrap.js"));
export function resolveMediaMaxBytes(
accountId?: string | null,
@@ -1,16 +1,12 @@
// Matrix plugin module implements plugin entry behavior.
import type { GatewayRequestHandlerOptions } from "openclaw/plugin-sdk/gateway-runtime";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
import { formatMatrixErrorMessage } from "./matrix/errors.js";
type MatrixVerificationRuntime = typeof import("./matrix/actions/verification.js");
let matrixVerificationRuntimePromise: Promise<MatrixVerificationRuntime> | undefined;
function loadMatrixVerificationRuntime(): Promise<MatrixVerificationRuntime> {
matrixVerificationRuntimePromise ??= import("./matrix/actions/verification.js");
return matrixVerificationRuntimePromise;
}
const loadMatrixVerificationRuntime = createLazyRuntimeModule(
() => import("./matrix/actions/verification.js"),
);
function sendError(respond: (ok: boolean, payload?: unknown) => void, err: unknown) {
respond(false, { error: formatMatrixErrorMessage(err) });
+4 -8
View File
@@ -1,14 +1,10 @@
// Matrix API module exposes the plugin public contract.
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/channel-entry-contract";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
type MatrixSubagentHooksModule = typeof import("./src/matrix/subagent-hooks.js");
let matrixSubagentHooksPromise: Promise<MatrixSubagentHooksModule> | null = null;
function loadMatrixSubagentHooksModule() {
matrixSubagentHooksPromise ??= import("./src/matrix/subagent-hooks.js");
return matrixSubagentHooksPromise;
}
const loadMatrixSubagentHooksModule = createLazyRuntimeModule(
() => import("./src/matrix/subagent-hooks.js"),
);
export function registerMatrixSubagentHooks(api: OpenClawPluginApi): void {
api.on("subagent_ended", async (event) => {
+4 -6
View File
@@ -1,3 +1,4 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Msteams plugin module implements sdk proactive behavior.
import { normalizeBotFrameworkServiceUrl } from "./bot-framework-service-url.js";
import {
@@ -69,12 +70,9 @@ type MSTeamsProactiveOptions = {
serviceUrlBoundary?: MSTeamsSdkCloudOptions;
};
let apiModulePromise: Promise<MSTeamsApiModule> | null = null;
async function loadMSTeamsApiModule(): Promise<MSTeamsApiModule> {
apiModulePromise ??= import("@microsoft/teams.api") as unknown as Promise<MSTeamsApiModule>;
return apiModulePromise;
}
const loadMSTeamsApiModule = createLazyRuntimeModule(
() => import("@microsoft/teams.api") as unknown as Promise<MSTeamsApiModule>,
);
function resolveThreadedConversationId(conversationId: string, threadActivityId?: string): string {
if (!threadActivityId) {
+18 -24
View File
@@ -1,5 +1,6 @@
// Msteams plugin module implements sdk behavior.
import * as fs from "node:fs";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { normalizeBotFrameworkServiceUrl } from "./bot-framework-service-url.js";
import type { MSTeamsCloudName } from "./cloud.js";
import type { MSTeamsCredentials, MSTeamsFederatedCredentials } from "./token.js";
@@ -199,31 +200,24 @@ type AzureIdentityModule = {
const AZURE_IDENTITY_MODULE = "@azure/identity";
let azureIdentityModulePromise: Promise<AzureIdentityModule> | null = null;
const loadAzureIdentity = createLazyRuntimeModule(
() => import(AZURE_IDENTITY_MODULE) as Promise<AzureIdentityModule>,
);
async function loadAzureIdentity(): Promise<AzureIdentityModule> {
azureIdentityModulePromise ??= import(AZURE_IDENTITY_MODULE) as Promise<AzureIdentityModule>;
return azureIdentityModulePromise;
}
let sdkAppPromise: Promise<TeamsSdkModules> | null = null;
async function loadSdkModules(): Promise<TeamsSdkModules> {
sdkAppPromise ??= Promise.all([
import("@microsoft/teams.apps"),
import("@microsoft/teams.api"),
]).then(([apps, api]) => ({
App: apps.App,
// ExpressAdapter is in the runtime barrel but its type is hidden behind
// the SDK's chained `export *` (see MSTeamsHttpServerAdapter comment).
// Cast to the structural constructor we model locally so the seam stays
// typed without depending on the SDK's namespace shape.
ExpressAdapter: (apps as unknown as { ExpressAdapter: MSTeamsExpressAdapterCtor })
.ExpressAdapter,
cloudFromName: (api as unknown as { cloudFromName: (name: string) => unknown }).cloudFromName,
}));
return sdkAppPromise;
}
const loadSdkModules = createLazyRuntimeModule(() =>
Promise.all([import("@microsoft/teams.apps"), import("@microsoft/teams.api")]).then(
([apps, api]) => ({
App: apps.App,
// ExpressAdapter is in the runtime barrel but its type is hidden behind
// the SDK's chained `export *` (see MSTeamsHttpServerAdapter comment).
// Cast to the structural constructor we model locally so the seam stays
// typed without depending on the SDK's namespace shape.
ExpressAdapter: (apps as unknown as { ExpressAdapter: MSTeamsExpressAdapterCtor })
.ExpressAdapter,
cloudFromName: (api as unknown as { cloudFromName: (name: string) => unknown }).cloudFromName,
}),
),
);
/**
* Lazily construct an ExpressAdapter that the Teams SDK App can register its
+4 -7
View File
@@ -23,6 +23,7 @@
* vitest (which resolves bare specifiers via `resolve.alias`, not Node CJS).
*/
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import {
hasConfiguredSecretInput,
normalizeResolvedSecretInputString,
@@ -38,13 +39,9 @@ import {
import type { FetchMediaOptions, FetchMediaResult } from "../engine/adapter/types.js";
import { getBridgeLogger } from "./logger.js";
let mediaRuntimeModulePromise: Promise<typeof import("openclaw/plugin-sdk/media-runtime")> | null =
null;
const loadMediaRuntimeModule = async () => {
mediaRuntimeModulePromise ??= import("openclaw/plugin-sdk/media-runtime");
return await mediaRuntimeModulePromise;
};
const loadMediaRuntimeModule = createLazyRuntimeModule(
() => import("openclaw/plugin-sdk/media-runtime"),
);
function createBuiltinAdapter(): PlatformAdapter {
return {
+6 -16
View File
@@ -8,9 +8,10 @@ import {
} from "openclaw/plugin-sdk/channel-outbound";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import type { ChannelPlugin } from "openclaw/plugin-sdk/core";
import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Register the PlatformAdapter before any core/ module is used.
import "./bridge/bootstrap.js";
import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
import { getQQBotApprovalCapability } from "./bridge/approval/capability.js";
import { qqbotConfigAdapter, qqbotMeta, qqbotSetupAdapterShared } from "./bridge/config-shared.js";
import {
@@ -34,21 +35,10 @@ import {
import { resolveQQBotGroupToolPolicy } from "./group-policy.js";
import type { ResolvedQQBotAccount } from "./types.js";
// Shared promise so concurrent multi-account startups serialize the dynamic
// import of the gateway module, avoiding an ESM circular-dependency race.
let gatewayModulePromise: Promise<typeof import("./bridge/gateway.js")> | undefined;
function loadGatewayModule(): Promise<typeof import("./bridge/gateway.js")> {
gatewayModulePromise ??= import("./bridge/gateway.js");
return gatewayModulePromise;
}
let outboundMessagingModulePromise:
| Promise<typeof import("./engine/messaging/outbound.js")>
| undefined;
function loadOutboundMessagingModule(): Promise<typeof import("./engine/messaging/outbound.js")> {
outboundMessagingModulePromise ??= import("./engine/messaging/outbound.js");
return outboundMessagingModulePromise;
}
const loadGatewayModule = createLazyRuntimeModule(() => import("./bridge/gateway.js"));
const loadOutboundMessagingModule = createLazyRuntimeModule(
() => import("./engine/messaging/outbound.js"),
);
function createQQBotSendReceipt(params: {
messageId?: string;
+4 -6
View File
@@ -13,6 +13,7 @@ import {
type ExecApprovalReplyDecision,
} from "openclaw/plugin-sdk/approval-reply-runtime";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import type { ReplyPayload } from "openclaw/plugin-sdk/reply-runtime";
import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
import {
@@ -75,7 +76,7 @@ type SignalApprovalDeliveryResult = {
meta?: Record<string, unknown>;
};
let resolverRuntimePromise: Promise<typeof import("./approval-resolver.js")> | undefined;
const resolverRuntimeLoader = createLazyRuntimeModule(() => import("./approval-resolver.js"));
const signalApprovalReactionTargets =
createApprovalReactionTargetStore<SignalApprovalReactionTarget>({
@@ -87,10 +88,7 @@ const signalApprovalReactionTargets =
readPersistedTarget,
});
function loadApprovalResolver(): Promise<typeof import("./approval-resolver.js")> {
resolverRuntimePromise ??= import("./approval-resolver.js");
return resolverRuntimePromise;
}
const loadApprovalResolver = resolverRuntimeLoader;
function resolveApprovalKindFromId(approvalId: string): ApprovalKind {
return approvalId.startsWith("plugin:") ? "plugin" : "exec";
@@ -756,5 +754,5 @@ export async function maybeResolveSignalApprovalReaction(params: {
export function clearSignalApprovalReactionTargetsForTest(): void {
signalApprovalReactionTargets.clearForTest();
resolverRuntimePromise = undefined;
resolverRuntimeLoader.clear();
}
+8 -22
View File
@@ -11,6 +11,7 @@ import {
attachChannelToResults,
} from "openclaw/plugin-sdk/channel-send-result";
import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
import { resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";
import { chunkText, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
@@ -40,34 +41,19 @@ import {
signalSecurityAdapter,
signalSetupWizard,
} from "./shared.js";
type SignalSendFn = typeof import("./send.runtime.js").sendMessageSignal;
type SignalProbe = import("./probe.js").SignalProbe;
type SignalApprovalReactionsModule = typeof import("./approval-reactions.js");
let signalMonitorModulePromise: Promise<typeof import("./monitor.js")> | null = null;
let signalProbeModulePromise: Promise<typeof import("./probe.js")> | null = null;
let signalSendRuntimePromise: Promise<typeof import("./send.runtime.js")> | null = null;
let signalApprovalReactionsModulePromise: Promise<SignalApprovalReactionsModule> | null = null;
const loadSignalMonitorModule = createLazyRuntimeModule(() => import("./monitor.js"));
async function loadSignalMonitorModule() {
signalMonitorModulePromise ??= import("./monitor.js");
return await signalMonitorModulePromise;
}
const loadSignalProbeModule = createLazyRuntimeModule(() => import("./probe.js"));
async function loadSignalProbeModule() {
signalProbeModulePromise ??= import("./probe.js");
return await signalProbeModulePromise;
}
const loadSignalSendRuntime = createLazyRuntimeModule(() => import("./send.runtime.js"));
async function loadSignalSendRuntime() {
signalSendRuntimePromise ??= import("./send.runtime.js");
return await signalSendRuntimePromise;
}
async function loadSignalApprovalReactionsModule() {
signalApprovalReactionsModulePromise ??= import("./approval-reactions.js");
return await signalApprovalReactionsModulePromise;
}
const loadSignalApprovalReactionsModule = createLazyRuntimeModule(
() => import("./approval-reactions.js"),
);
async function resolveSignalSendContext(params: {
cfg: Parameters<typeof resolveSignalAccount>[0]["cfg"];
+9 -38
View File
@@ -2,6 +2,7 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { isLoopbackHost } from "openclaw/plugin-sdk/gateway-runtime";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import {
consultRealtimeVoiceAgent,
REALTIME_VOICE_AGENT_CONSULT_TOOL_NAME,
@@ -57,13 +58,6 @@ type Logger = {
type ResolvedRealtimeProvider = ResolvedRealtimeVoiceProvider;
type TelnyxProviderModule = typeof import("./providers/telnyx.js");
type TwilioProviderModule = typeof import("./providers/twilio.js");
type PlivoProviderModule = typeof import("./providers/plivo.js");
type MockProviderModule = typeof import("./providers/mock.js");
type RealtimeVoiceRuntimeModule = typeof import("./realtime-voice.runtime.js");
type RealtimeHandlerModule = typeof import("./webhook/realtime-handler.js");
const REALTIME_VOICE_CONSULT_SYSTEM_PROMPT = [
"You are the configured OpenClaw agent receiving delegated requests from a live phone voice bridge.",
"Act on behalf of the caller using the normal available tools when the caller asks you to do work.",
@@ -73,42 +67,19 @@ const REALTIME_VOICE_CONSULT_SYSTEM_PROMPT = [
"Be accurate, brief, and speakable.",
].join(" ");
let telnyxProviderPromise: Promise<TelnyxProviderModule> | undefined;
let twilioProviderPromise: Promise<TwilioProviderModule> | undefined;
let plivoProviderPromise: Promise<PlivoProviderModule> | undefined;
let mockProviderPromise: Promise<MockProviderModule> | undefined;
let realtimeVoiceRuntimePromise: Promise<RealtimeVoiceRuntimeModule> | undefined;
let realtimeHandlerPromise: Promise<RealtimeHandlerModule> | undefined;
const loadTelnyxProvider = createLazyRuntimeModule(() => import("./providers/telnyx.js"));
function loadTelnyxProvider(): Promise<TelnyxProviderModule> {
telnyxProviderPromise ??= import("./providers/telnyx.js");
return telnyxProviderPromise;
}
const loadTwilioProvider = createLazyRuntimeModule(() => import("./providers/twilio.js"));
function loadTwilioProvider(): Promise<TwilioProviderModule> {
twilioProviderPromise ??= import("./providers/twilio.js");
return twilioProviderPromise;
}
const loadPlivoProvider = createLazyRuntimeModule(() => import("./providers/plivo.js"));
function loadPlivoProvider(): Promise<PlivoProviderModule> {
plivoProviderPromise ??= import("./providers/plivo.js");
return plivoProviderPromise;
}
const loadMockProvider = createLazyRuntimeModule(() => import("./providers/mock.js"));
function loadMockProvider(): Promise<MockProviderModule> {
mockProviderPromise ??= import("./providers/mock.js");
return mockProviderPromise;
}
const loadRealtimeVoiceRuntime = createLazyRuntimeModule(
() => import("./realtime-voice.runtime.js"),
);
function loadRealtimeVoiceRuntime(): Promise<RealtimeVoiceRuntimeModule> {
realtimeVoiceRuntimePromise ??= import("./realtime-voice.runtime.js");
return realtimeVoiceRuntimePromise;
}
function loadRealtimeHandler(): Promise<RealtimeHandlerModule> {
realtimeHandlerPromise ??= import("./webhook/realtime-handler.js");
return realtimeHandlerPromise;
}
const loadRealtimeHandler = createLazyRuntimeModule(() => import("./webhook/realtime-handler.js"));
function resolveVoiceCallConsultSessionKey(call: {
config: VoiceCallConfig;
+7 -14
View File
@@ -2,6 +2,7 @@
import http from "node:http";
import { URL } from "node:url";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import {
asDateTimestampMs,
resolveExpiresAtMsFromDurationMs,
@@ -46,9 +47,6 @@ const WEBHOOK_BODY_TIMEOUT_MS = WEBHOOK_BODY_READ_DEFAULTS.preAuth.timeoutMs;
const MISSING_REMOTE_ADDRESS_IN_FLIGHT_KEY = "__voice_call_no_remote__";
const STREAM_DISCONNECT_HANGUP_GRACE_MS = 2000;
const TRANSCRIPT_LOG_MAX_CHARS = 200;
type RealtimeTranscriptionRuntime = typeof import("./realtime-transcription.runtime.js");
type ResponseGeneratorModule = typeof import("./response-generator.js");
type Logger = {
info: (message: string) => void;
warn: (message: string) => void;
@@ -56,18 +54,13 @@ type Logger = {
debug?: (message: string) => void;
};
let realtimeTranscriptionRuntimePromise: Promise<RealtimeTranscriptionRuntime> | undefined;
let responseGeneratorModulePromise: Promise<ResponseGeneratorModule> | undefined;
const loadRealtimeTranscriptionRuntime = createLazyRuntimeModule(
() => import("./realtime-transcription.runtime.js"),
);
function loadRealtimeTranscriptionRuntime(): Promise<RealtimeTranscriptionRuntime> {
realtimeTranscriptionRuntimePromise ??= import("./realtime-transcription.runtime.js");
return realtimeTranscriptionRuntimePromise;
}
function loadResponseGeneratorModule(): Promise<ResponseGeneratorModule> {
responseGeneratorModulePromise ??= import("./response-generator.js");
return responseGeneratorModulePromise;
}
const loadResponseGeneratorModule = createLazyRuntimeModule(
() => import("./response-generator.js"),
);
type WebhookHeaderGateResult =
| { ok: true }
+2 -6
View File
@@ -1,13 +1,9 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Whatsapp plugin module implements login qr runtime behavior.
type StartWebLoginWithQr = typeof import("./src/login-qr.js").startWebLoginWithQr;
type WaitForWebLogin = typeof import("./src/login-qr.js").waitForWebLogin;
let loginQrModulePromise: Promise<typeof import("./src/login-qr.js")> | null = null;
function loadLoginQrModule() {
loginQrModulePromise ??= import("./src/login-qr.js");
return loginQrModulePromise;
}
const loadLoginQrModule = createLazyRuntimeModule(() => import("./src/login-qr.js"));
export async function startWebLoginWithQr(
...args: Parameters<StartWebLoginWithQr>
@@ -9,6 +9,7 @@ import {
} from "openclaw/plugin-sdk/approval-reaction-runtime";
import type { ExecApprovalReplyDecision } from "openclaw/plugin-sdk/approval-reply-runtime";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { getWhatsAppApprovalApprovers, whatsappApprovalAuth } from "./approval-auth.js";
import { getOptionalWhatsAppRuntime } from "./runtime.js";
@@ -36,7 +37,7 @@ type ResolvedWhatsAppApprovalReactionTarget = WhatsAppApprovalReactionResolution
remoteJid: string;
};
let resolverRuntimePromise: Promise<typeof import("./approval-resolver.js")> | undefined;
const resolverRuntimeLoader = createLazyRuntimeModule(() => import("./approval-resolver.js"));
const whatsappApprovalReactionTargets =
createApprovalReactionTargetStore<WhatsAppApprovalReactionTarget>({
@@ -48,10 +49,7 @@ const whatsappApprovalReactionTargets =
readPersistedTarget,
});
function loadApprovalResolver(): Promise<typeof import("./approval-resolver.js")> {
resolverRuntimePromise ??= import("./approval-resolver.js");
return resolverRuntimePromise;
}
const loadApprovalResolver = resolverRuntimeLoader;
function buildReactionTargetKey(params: {
accountId: string;
@@ -398,5 +396,5 @@ export async function maybeResolveWhatsAppApprovalReaction(params: {
export function clearWhatsAppApprovalReactionTargetsForTest(): void {
whatsappApprovalReactionTargets.clearForTest();
resolverRuntimePromise = undefined;
resolverRuntimeLoader.clear();
}
@@ -7,6 +7,7 @@ import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runti
import { formatCliCommand } from "openclaw/plugin-sdk/cli-runtime";
import { isControlCommandMessage } from "openclaw/plugin-sdk/command-detection";
import { drainPendingDeliveries } from "openclaw/plugin-sdk/delivery-queue-runtime";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { DEFAULT_GROUP_HISTORY_LIMIT } from "openclaw/plugin-sdk/reply-history";
import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
@@ -65,13 +66,9 @@ function isNonRetryableWebCloseStatus(statusCode: unknown): boolean {
type ReplyResolver = typeof import("./reply-resolver.runtime.js").getReplyFromConfig;
type WhatsAppRuntimeConfig = ReturnType<typeof getRuntimeConfig>;
let replyResolverRuntimePromise: Promise<typeof import("./reply-resolver.runtime.js")> | null =
null;
function loadReplyResolverRuntime() {
replyResolverRuntimePromise ??= import("./reply-resolver.runtime.js");
return replyResolverRuntimePromise;
}
const loadReplyResolverRuntime = createLazyRuntimeModule(
() => import("./reply-resolver.runtime.js"),
);
function resolveWebMonitorConfigSnapshot(params: {
cfg: WhatsAppRuntimeConfig;
+2 -8
View File
@@ -1,19 +1,13 @@
// Whatsapp plugin module implements outbound adapter behavior.
import type { ChannelOutboundAdapter } from "openclaw/plugin-sdk/channel-send-result";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { chunkText } from "openclaw/plugin-sdk/reply-chunking";
import { shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
import { createWhatsAppOutboundBase } from "./outbound-base.js";
import { normalizeWhatsAppPayloadText } from "./outbound-media-contract.js";
import { resolveWhatsAppOutboundTarget } from "./resolve-outbound-target.js";
type WhatsAppSendModule = typeof import("./send.js");
let whatsAppSendModulePromise: Promise<WhatsAppSendModule> | undefined;
function loadWhatsAppSendModule(): Promise<WhatsAppSendModule> {
whatsAppSendModulePromise ??= import("./send.js");
return whatsAppSendModulePromise;
}
const loadWhatsAppSendModule = createLazyRuntimeModule(() => import("./send.js"));
function normalizeOutboundText(text: string | undefined): string {
return normalizeWhatsAppPayloadText(text);
+2 -6
View File
@@ -1,3 +1,4 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Whatsapp API module exposes the plugin public contract.
export { getChatChannelMeta, type ChannelPlugin } from "openclaw/plugin-sdk/core";
export { buildChannelConfigSchema, WhatsAppConfigSchema } from "../config-api.js";
@@ -45,12 +46,7 @@ export type { WhatsAppAccountConfig } from "./account-types.js";
type MonitorWebChannel = typeof import("./channel.runtime.js").monitorWebChannel;
let channelRuntimePromise: Promise<typeof import("./channel.runtime.js")> | null = null;
function loadChannelRuntime() {
channelRuntimePromise ??= import("./channel.runtime.js");
return channelRuntimePromise;
}
const loadChannelRuntime = createLazyRuntimeModule(() => import("./channel.runtime.js"));
export async function monitorWebChannel(
...args: Parameters<MonitorWebChannel>
+3 -7
View File
@@ -5,6 +5,7 @@ import { resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-
import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pairing";
import type { MarkdownTableMode, OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import { resolveInboundRouteEnvelopeBuilderWithRuntime } from "openclaw/plugin-sdk/inbound-envelope";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
import {
deliverTextOrMediaReply,
@@ -34,6 +35,7 @@ import {
import { normalizeZaloAllowEntry, resolveZaloRuntimeGroupPolicy } from "./group-access.js";
import { resolveZaloProxyFetch } from "./proxy.js";
import { getZaloRuntime } from "./runtime.js";
export type { ZaloRuntimeEnv } from "./monitor.types.js";
import {
prepareZaloDurableReplyPayload,
@@ -68,7 +70,6 @@ const UNIX_MILLISECONDS_THRESHOLD = 1_000_000_000_000;
type ZaloCoreRuntime = ReturnType<typeof getZaloRuntime>;
type ZaloStatusSink = (patch: { lastInboundAt?: number; lastOutboundAt?: number }) => void;
type ZaloWebhookModule = typeof import("./monitor.webhook.js");
type ZaloProcessingContext = {
token: string;
account: ResolvedZaloAccount;
@@ -90,8 +91,6 @@ type ZaloPollingLoopParams = ZaloProcessingContext & {
type ZaloUpdateProcessingParams = ZaloProcessingContext & {
update: ZaloUpdate;
};
let zaloWebhookModulePromise: Promise<ZaloWebhookModule> | undefined;
const hostedMediaRouteRefs = new Map<string, { count: number; unregisters: Array<() => void> }>();
function resolveZaloTimestampMs(date: number | undefined): number | undefined {
@@ -101,10 +100,7 @@ function resolveZaloTimestampMs(date: number | undefined): number | undefined {
return date >= UNIX_MILLISECONDS_THRESHOLD ? date : date * 1000;
}
function loadZaloWebhookModule(): Promise<ZaloWebhookModule> {
zaloWebhookModulePromise ??= import("./monitor.webhook.js");
return zaloWebhookModulePromise;
}
const loadZaloWebhookModule = createLazyRuntimeModule(() => import("./monitor.webhook.js"));
function releaseSharedHostedMediaRouteRef(routePath: string): void {
const current = hostedMediaRouteRefs.get(routePath);
@@ -1,5 +1,6 @@
// Zalo plugin module implements monitor mocks test support behavior.
import { createPluginRuntimeMock } from "openclaw/plugin-sdk/channel-test-helpers";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import {
createEmptyPluginRegistry,
createRuntimeEnv,
@@ -23,7 +24,6 @@ type UnknownMock = Mock<(...args: unknown[]) => unknown>;
type AsyncUnknownMock = Mock<(...args: unknown[]) => Promise<unknown>>;
const loadedMonitorModules = new Set<MonitorModule>();
const cachedMonitorModules = new Map<string, Promise<MonitorModule>>();
let cachedWebhookModule: Promise<WebhookModule> | undefined;
type ZaloLifecycleMocks = {
setWebhookMock: AsyncUnknownMock;
@@ -102,10 +102,9 @@ async function importSecretInputModule(cacheBust: string): Promise<SecretInputMo
)) as SecretInputModule;
}
async function importCachedWebhookModule(): Promise<WebhookModule> {
cachedWebhookModule ??= import(webhookModuleUrl) as Promise<WebhookModule>;
return await cachedWebhookModule;
}
const importCachedWebhookModule = createLazyRuntimeModule(
() => import(webhookModuleUrl) as Promise<WebhookModule>,
);
export async function resetLifecycleTestState() {
vi.clearAllMocks();
+2 -6
View File
@@ -6,15 +6,11 @@ import {
resolveMergedAccountConfig,
} from "openclaw/plugin-sdk/account-resolution";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
import type { ResolvedZalouserAccount, ZalouserAccountConfig, ZalouserConfig } from "./types.js";
let zalouserAccountsRuntimePromise: Promise<typeof import("./accounts.runtime.js")> | undefined;
async function loadZalouserAccountsRuntime() {
zalouserAccountsRuntimePromise ??= import("./accounts.runtime.js");
return await zalouserAccountsRuntimePromise;
}
const loadZalouserAccountsRuntime = createLazyRuntimeModule(() => import("./accounts.runtime.js"));
const {
listAccountIds: listZalouserAccountIds,
+6 -7
View File
@@ -1,3 +1,4 @@
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
// Zalouser plugin module implements zca client behavior.
import {
LoginQRCallbackEventType,
@@ -10,14 +11,12 @@ import {
type ZcaJsRuntime = {
Zalo: unknown;
};
let zcaJsRuntimePromise: Promise<ZcaJsRuntime> | null = null;
async function loadZcaJsRuntime(): Promise<ZcaJsRuntime> {
// Keep zca-js behind a runtime boundary so bundled metadata/contracts can load
// without resolving its optional WebSocket dependency tree.
zcaJsRuntimePromise ??= import("zca-js").then((mod) => mod as unknown as ZcaJsRuntime);
return await zcaJsRuntimePromise;
}
// Keep zca-js behind a runtime boundary so bundled metadata/contracts can load
// without resolving its optional WebSocket dependency tree.
const loadZcaJsRuntime = createLazyRuntimeModule(() =>
import("zca-js").then((mod) => mod as unknown as ZcaJsRuntime),
);
export { LoginQRCallbackEventType, Reactions, TextStyle, ThreadType };
export type { Style };