diff --git a/extensions/browser/src/browser/runtime-lifecycle.ts b/extensions/browser/src/browser/runtime-lifecycle.ts index 7b181faea6e..87602ff281e 100644 --- a/extensions/browser/src/browser/runtime-lifecycle.ts +++ b/extensions/browser/src/browser/runtime-lifecycle.ts @@ -1,4 +1,5 @@ import type { Server } from "node:http"; +import { getPwAiModule } from "./pw-ai-module.js"; import { isPwAiLoaded } from "./pw-ai-state.js"; import type { BrowserServerState } from "./server-context.js"; import { ensureExtensionRelayForProfiles, stopKnownBrowserProfiles } from "./server-lifecycle.js"; @@ -52,8 +53,8 @@ export async function stopBrowserRuntime(params: { return; } try { - const mod = await import("./pw-ai.js"); - await mod.closePlaywrightBrowserConnection(); + const mod = await getPwAiModule({ mode: "soft" }); + await mod?.closePlaywrightBrowserConnection(); } catch { // ignore } diff --git a/extensions/browser/src/browser/server-context.lifecycle.ts b/extensions/browser/src/browser/server-context.lifecycle.ts index 17af693d73f..4399cb2bde6 100644 --- a/extensions/browser/src/browser/server-context.lifecycle.ts +++ b/extensions/browser/src/browser/server-context.lifecycle.ts @@ -1,5 +1,6 @@ import type { ResolvedBrowserProfile } from "./config.js"; import { getBrowserProfileCapabilities } from "./profile-capabilities.js"; +import { getPwAiModule } from "./pw-ai-module.js"; export function resolveIdleProfileStopOutcome(profile: ResolvedBrowserProfile): { stopped: boolean; @@ -20,8 +21,8 @@ export function resolveIdleProfileStopOutcome(profile: ResolvedBrowserProfile): export async function closePlaywrightBrowserConnectionForProfile(cdpUrl?: string): Promise { try { - const mod = await import("./pw-ai.js"); - await mod.closePlaywrightBrowserConnection(cdpUrl ? { cdpUrl } : undefined); + const mod = await getPwAiModule({ mode: "soft" }); + await mod?.closePlaywrightBrowserConnection(cdpUrl ? { cdpUrl } : undefined); } catch { // ignore } diff --git a/extensions/browser/src/browser/server-context.reset.ts b/extensions/browser/src/browser/server-context.reset.ts index ea478f56f31..c5bb2e567f5 100644 --- a/extensions/browser/src/browser/server-context.reset.ts +++ b/extensions/browser/src/browser/server-context.reset.ts @@ -2,6 +2,7 @@ import fs from "node:fs"; import type { ResolvedBrowserProfile } from "./config.js"; import { BrowserResetUnsupportedError } from "./errors.js"; import { getBrowserProfileCapabilities } from "./profile-capabilities.js"; +import { getPwAiModule } from "./pw-ai-module.js"; import type { ProfileRuntimeState } from "./server-context.types.js"; import { movePathToTrash } from "./trash.js"; @@ -19,8 +20,8 @@ type ResetOps = { async function closePlaywrightBrowserConnectionForProfile(cdpUrl?: string): Promise { try { - const mod = await import("./pw-ai.js"); - await mod.closePlaywrightBrowserConnection(cdpUrl ? { cdpUrl } : undefined); + const mod = await getPwAiModule({ mode: "soft" }); + await mod?.closePlaywrightBrowserConnection(cdpUrl ? { cdpUrl } : undefined); } catch { // ignore } diff --git a/extensions/voice-call/src/webhook.ts b/extensions/voice-call/src/webhook.ts index 441bd23023c..e3cbbc0ad32 100644 --- a/extensions/voice-call/src/webhook.ts +++ b/extensions/voice-call/src/webhook.ts @@ -31,6 +31,22 @@ const WEBHOOK_BODY_TIMEOUT_MS = WEBHOOK_BODY_READ_DEFAULTS.preAuth.timeoutMs; 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"); + +let realtimeTranscriptionRuntimePromise: Promise | undefined; +let responseGeneratorModulePromise: Promise | undefined; + +function loadRealtimeTranscriptionRuntime(): Promise { + realtimeTranscriptionRuntimePromise ??= import("./realtime-transcription.runtime.js"); + return realtimeTranscriptionRuntimePromise; +} + +function loadResponseGeneratorModule(): Promise { + responseGeneratorModulePromise ??= import("./response-generator.js"); + return responseGeneratorModulePromise; +} + type WebhookHeaderGateResult = | { ok: true } | { @@ -233,7 +249,7 @@ export class VoiceCallWebhookServer { const pluginConfig = this.fullConfig ?? (this.coreConfig as unknown as OpenClawConfig | undefined); const { getRealtimeTranscriptionProvider, listRealtimeTranscriptionProviders } = - await import("./realtime-transcription.runtime.js"); + await loadRealtimeTranscriptionRuntime(); const resolution = resolveConfiguredCapabilityProvider({ configuredProviderId: streaming.provider, providerConfigs: streaming.providers, @@ -762,7 +778,7 @@ export class VoiceCallWebhookServer { } try { - const { generateVoiceResponse } = await import("./response-generator.js"); + const { generateVoiceResponse } = await loadResponseGeneratorModule(); const result = await generateVoiceResponse({ voiceConfig: this.config, diff --git a/extensions/xai/index.ts b/extensions/xai/index.ts index ce35dd0e56b..2d56fa9731a 100644 --- a/extensions/xai/index.ts +++ b/extensions/xai/index.ts @@ -25,14 +25,21 @@ import { const PROVIDER_ID = "xai"; type CodeExecutionModule = typeof import("./code-execution.js"); +type XSearchModule = typeof import("./x-search.js"); let codeExecutionModulePromise: Promise | undefined; +let xSearchModulePromise: Promise | undefined; function loadCodeExecutionModule(): Promise { codeExecutionModulePromise ??= import("./code-execution.js"); return codeExecutionModulePromise; } +function loadXSearchModule(): Promise { + xSearchModulePromise ??= import("./x-search.js"); + return xSearchModulePromise; +} + function hasResolvableXaiApiKey(config: unknown): boolean { return Boolean( resolveFallbackXaiAuth(config as never)?.apiKey || readProviderEnvValue(["XAI_API_KEY"]), @@ -126,7 +133,7 @@ function createLazyXSearchTool(ctx: { } return createXSearchToolDefinition(async (toolCallId: string, args: Record) => { - const { createXSearchTool } = await import("./x-search.js"); + const { createXSearchTool } = await loadXSearchModule(); const tool = createXSearchTool({ config: ctx.config as never, runtimeConfig: (ctx.runtimeConfig as never) ?? null,