refactor: cache remaining runtime imports

This commit is contained in:
Peter Steinberger
2026-04-18 20:07:55 +01:00
parent 58759bb565
commit a5d6330f87
5 changed files with 35 additions and 9 deletions

View File

@@ -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
}

View File

@@ -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<void> {
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
}

View File

@@ -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<void> {
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
}

View File

@@ -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<RealtimeTranscriptionRuntime> | undefined;
let responseGeneratorModulePromise: Promise<ResponseGeneratorModule> | undefined;
function loadRealtimeTranscriptionRuntime(): Promise<RealtimeTranscriptionRuntime> {
realtimeTranscriptionRuntimePromise ??= import("./realtime-transcription.runtime.js");
return realtimeTranscriptionRuntimePromise;
}
function loadResponseGeneratorModule(): Promise<ResponseGeneratorModule> {
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,

View File

@@ -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<CodeExecutionModule> | undefined;
let xSearchModulePromise: Promise<XSearchModule> | undefined;
function loadCodeExecutionModule(): Promise<CodeExecutionModule> {
codeExecutionModulePromise ??= import("./code-execution.js");
return codeExecutionModulePromise;
}
function loadXSearchModule(): Promise<XSearchModule> {
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<string, unknown>) => {
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,