UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

425 lines (424 loc) 16.9 kB
import { n as getRuntimeConfig } from "./io.runtime-B9iJRs3w.js"; import { t as normalizePluginPolicyId } from "./plugin-policy-id-4QxPdFqy.js"; import { o as resolveCompatibilityHostVersion } from "./version-v1kuAkGj.js"; import { h as withBundledPluginEnablementCompat } from "./installed-plugin-index-wrDsjyMD.js"; import { r as hasKind } from "./slots-CQdAEuat.js"; import { l as normalizePluginsConfig } from "./config-state-BkU1frVq.js"; import { a as projectPluginDependencyHealth, r as buildPluginDependencyStatus, s as tracePluginLifecyclePhase } from "./discovery-D_VDsZuY.js"; import { n as normalizeOpenClawVersionBase } from "./version-BXayNebU.js"; import { a as loadPluginMetadataSnapshot } from "./plugin-metadata-snapshot-w-4EjxI4.js"; import { n as resolvePluginControlPlaneWorkspace, t as appendPluginControlPlaneWorkspaceDiagnostic } from "./control-plane-workspace-BWhgt2gz.js"; import { r as listImportedBundledPluginFacadeIds } from "./facade-loader-CVT-xVW5.js"; import "./config-Cs0XXL3x.js"; import { v as listImportedRuntimePluginIds } from "./runtime-BL4wZfTq.js"; import { n as inspectBundleMcpRuntimeSupport, r as inspectNativePluginMcpRuntimeSupport } from "./bundle-mcp-zo_t2klC.js"; import "./facade-runtime-BjmVS_9G.js"; import { s as resolveCompatibleRuntimePluginRegistry } from "./active-runtime-registry-C5SJbS7x.js"; import { r as resolveBundledProviderCompatPluginIds } from "./providers-DCe4UB6a.js"; import { n as loadPluginRegistryHandle } from "./loader-DPiOPJjR.js"; import { a as tracksPluginDependencyStatus } from "./official-external-plugin-repair-hints-CXeFydKX.js"; import { t as buildPluginRuntimeLoadOptions } from "./load-context-BdeWeJHL.js"; import { t as resolvePluginRuntimeLoadContext } from "./load-context.resolve-O967gh1f.js"; import { t as inspectBundleLspRuntimeSupport } from "./bundle-lsp-TidsbhfG.js"; import { t as resolveEffectivePluginIds } from "./effective-plugin-ids-C8jx2RTW.js"; import { t as loadPluginMetadataRegistrySnapshot } from "./metadata-registry-loader-C82_GM3n.js"; import { t as formatPluginCompatibilityNotice } from "./status-compatibility-DdQ1VWdc.js"; import { n as collectPluginCapabilityConsentDiagnostics } from "./status-snapshot-kuewDRMh.js"; //#region src/plugins/inspect-shape.ts function buildPluginCapabilityEntries(plugin, report) { return [ { kind: "cli-backend", ids: plugin.cliBackendIds ?? [] }, { kind: "text-inference", ids: plugin.providerIds }, { kind: "embedding", ids: plugin.embeddingProviderIds }, { kind: "speech", ids: plugin.speechProviderIds }, { kind: "realtime-transcription", ids: plugin.realtimeTranscriptionProviderIds }, { kind: "realtime-voice", ids: plugin.realtimeVoiceProviderIds }, { kind: "media-understanding", ids: plugin.mediaUnderstandingProviderIds }, { kind: "transcript-source", ids: plugin.transcriptSourceProviderIds }, { kind: "document-extractors", ids: plugin.contracts?.documentExtractors ?? [] }, { kind: "image-generation", ids: plugin.imageGenerationProviderIds }, { kind: "video-generation", ids: plugin.videoGenerationProviderIds }, { kind: "music-generation", ids: plugin.musicGenerationProviderIds }, { kind: "web-content-extractors", ids: plugin.contracts?.webContentExtractors ?? [] }, { kind: "web-fetch", ids: plugin.webFetchProviderIds }, { kind: "web-search", ids: plugin.webSearchProviderIds }, { kind: "migration-provider", ids: plugin.migrationProviderIds }, { kind: "worker-provider", ids: plugin.contracts?.workerProviders ?? [] }, { kind: "session-catalog", ids: report.sessionCatalogs.filter((entry) => entry.pluginId === plugin.id).map((entry) => entry.provider.id) }, { kind: "agent-harness", ids: plugin.agentHarnessIds }, { kind: "context-engine", ids: plugin.status === "loaded" && hasKind(plugin.kind, "context-engine") ? plugin.contextEngineIds ?? [] : [] }, { kind: "channel", ids: plugin.channelIds }, { kind: "gateway-discovery", ids: plugin.gatewayDiscoveryServiceIds } ].filter((entry) => entry.ids.length > 0); } function derivePluginInspectShape({ plugin, report }, capabilityCount) { if (capabilityCount > 1) return "hybrid-capability"; if (capabilityCount === 1) return "plain-capability"; if (plugin.commands.length === 0 && plugin.cliCommands.length === 0 && plugin.services.length === 0 && plugin.httpRoutes === 0 && (report.typedHooks.some((entry) => entry.pluginId === plugin.id) || report.hooks.some((entry) => entry.pluginId === plugin.id)) && !report.tools.some((entry) => entry.pluginId === plugin.id) && !(report.gatewayMethodDescriptors ?? []).some((descriptor) => descriptor.owner.kind === "plugin" && descriptor.owner.pluginId === plugin.id)) return "hook-only"; return "non-capability"; } function buildPluginShapeSummary(params) { const capabilities = buildPluginCapabilityEntries(params.plugin, params.report); const capabilityCount = capabilities.length; return { shape: derivePluginInspectShape(params, capabilityCount), capabilityMode: capabilityCount === 0 ? "none" : capabilityCount === 1 ? "plain" : "hybrid", capabilityCount, capabilities }; } //#endregion //#region src/plugins/status.ts function buildCompatibilityNoticesForInspect(inspect) { const warnings = []; if (inspect.shape === "hook-only") warnings.push({ pluginId: inspect.plugin.id, code: "hook-only", compatCode: "hook-only-plugin-shape", severity: "info", message: "is hook-only. This remains a supported compatibility path, but it has not migrated to explicit capability registration yet." }); if (usesRemovedSessionTranscriptFileApi(inspect)) warnings.push({ pluginId: inspect.plugin.id, code: "removed-session-transcript-file-api", compatCode: "removed-session-transcript-file-api", severity: "warn", message: "references removed session/transcript file APIs; migrate to session identity, SessionTranscriptUpdate.target, and Gateway/runtime session helpers." }); return warnings; } const removedSessionTranscriptFileApiMarkers = [ "saveSessionStore", "resolveSessionTranscriptPathInDir", "resolveAndPersistSessionFile", "readLatestAssistantTextFromSessionTranscript", "SessionTranscriptUpdate.sessionFile", "sessionFiles", "transcriptPath", "sessionFile" ]; function usesRemovedSessionTranscriptFileApi(inspect) { if (inspect.plugin.origin === "bundled") return false; return [inspect.plugin.error, ...inspect.diagnostics.map((diagnostic) => diagnostic.message)].filter((message) => typeof message === "string" && message.length > 0).some((message) => removedSessionTranscriptFileApiMarkers.some((marker) => message.includes(marker))); } function resolveReportedPluginVersion(plugin, env) { if (plugin.origin !== "bundled") return plugin.version; return normalizeOpenClawVersionBase(resolveCompatibilityHostVersion(env)) ?? normalizeOpenClawVersionBase(plugin.version) ?? plugin.version; } function buildPluginReport(params, loadModules) { const rawConfig = params?.config ?? getRuntimeConfig(); const workspace = resolvePluginControlPlaneWorkspace({ config: rawConfig, env: params?.env, workspaceDir: params?.workspaceDir }); const initialWorkspaceDir = workspace.workspaceDir; const metadataSnapshot = params?.metadataSnapshot ?? loadPluginMetadataSnapshot({ config: rawConfig, env: params?.env ?? process.env, workspaceDir: initialWorkspaceDir, ...params?.onlyPluginIds !== void 0 ? { pluginIds: params.onlyPluginIds } : {} }); const baseContext = resolvePluginRuntimeLoadContext({ config: rawConfig, env: params?.env, logger: params?.logger, workspaceDir: initialWorkspaceDir, onlyPluginIds: params?.onlyPluginIds, metadataSnapshot }); const workspaceDir = baseContext.workspaceDir ?? initialWorkspaceDir; const context = workspaceDir === baseContext.workspaceDir ? baseContext : { ...baseContext, workspaceDir }; const manifestByPluginId = metadataSnapshot.byPluginId; const packageBuildByPluginId = new Map(metadataSnapshot.index.plugins.map((plugin) => [plugin.pluginId, plugin.packageBuild])); const config = context.config; const bundledProviderIds = resolveBundledProviderCompatPluginIds({ config, workspaceDir, env: params?.env, manifestRegistry: metadataSnapshot.manifestRegistry }); const runtimeCompatConfig = withBundledPluginEnablementCompat({ config, pluginIds: bundledProviderIds, ...params?.env ? { env: params.env } : {}, activation: "defaults" }); const onlyPluginIds = params?.effectiveOnly === true ? resolveEffectivePluginIds({ config: rawConfig, workspaceDir, env: params?.env ?? process.env, metadataSnapshot }) : params?.onlyPluginIds === void 0 ? void 0 : [...params.onlyPluginIds]; const registry = loadModules ? tracePluginLifecyclePhase("runtime plugin registry load", () => loadPluginRegistryHandle(buildPluginRuntimeLoadOptions(context, { config: runtimeCompatConfig, activationSourceConfig: rawConfig, workspaceDir, env: params?.env, loadModules, cache: false, onlyPluginIds, toolDiscovery: params?.runtimeInspection })), { surface: "status", onlyPluginCount: onlyPluginIds?.length }) : tracePluginLifecyclePhase("plugin registry snapshot", () => loadPluginMetadataRegistrySnapshot({ config: runtimeCompatConfig, activationSourceConfig: rawConfig, workspaceDir, env: params?.env, logger: params?.logger, loadModules: false, onlyPluginIds, manifestRegistry: metadataSnapshot.manifestRegistry, runtimeContext: context }), { surface: "status", onlyPluginCount: onlyPluginIds?.length }); const importedPluginIds = /* @__PURE__ */ new Set([ ...loadModules ? registry.plugins.filter((plugin) => plugin.status === "loaded" && plugin.format !== "bundle").map((plugin) => plugin.id) : [], ...listImportedRuntimePluginIds(), ...listImportedBundledPluginFacadeIds() ]); return projectPluginDependencyHealth({ workspaceDir, workspaceScope: workspace.workspaceScope, ...registry, diagnostics: appendPluginControlPlaneWorkspaceDiagnostic([...registry.diagnostics, ...collectPluginCapabilityConsentDiagnostics({ index: metadataSnapshot.index, manifests: manifestByPluginId })], workspace), plugins: registry.plugins.map((plugin) => Object.assign({}, plugin, { imported: plugin.format !== `bundle` && importedPluginIds.has(plugin.id), version: resolveReportedPluginVersion(plugin, params?.env), dependencyStatus: plugin.dependencyStatus ?? (tracksPluginDependencyStatus({ origin: plugin.origin, pluginId: plugin.id, packageName: plugin.packageName ?? manifestByPluginId.get(plugin.id)?.packageName, packageBuild: packageBuildByPluginId.get(plugin.id) }) ? buildPluginDependencyStatus({ rootDir: plugin.rootDir, dependencies: manifestByPluginId.get(plugin.id)?.packageDependencies, optionalDependencies: manifestByPluginId.get(plugin.id)?.packageOptionalDependencies }) : void 0) })) }); } function buildPluginSnapshotReport(params) { return buildPluginReport(params, false); } function buildPluginDiagnosticsReport(params) { return buildPluginReport(params, true); } function resolvePluginInspectContext({ report, ...params }) { const { rawConfig, config } = resolvePluginRuntimeLoadContext(params); return { report: report ?? buildPluginDiagnosticsReport({ ...params, config: rawConfig }), entries: normalizePluginsConfig(config.plugins).entries }; } function buildPluginInspectReport({ id, ...params }) { const context = resolvePluginInspectContext(params); const plugin = context.report.plugins.find((entry) => entry.id === id) ?? context.report.plugins.find((entry) => entry.name === id); return plugin ? buildPluginInspectRecord(plugin, context) : null; } function buildPluginInspectRecord(plugin, { report, entries }) { const typedHooks = report.typedHooks.filter((entry) => entry.pluginId === plugin.id).map((entry) => ({ name: entry.hookName, priority: entry.priority })).toSorted((a, b) => a.name.localeCompare(b.name)); const customHooks = report.hooks.filter((entry) => entry.pluginId === plugin.id).map((entry) => ({ name: entry.entry.hook.name, events: [...entry.events].toSorted() })).toSorted((a, b) => a.name.localeCompare(b.name)); const tools = report.tools.filter((entry) => entry.pluginId === plugin.id).map((entry) => ({ names: [...entry.names], optional: entry.optional })); const diagnostics = report.diagnostics.filter((entry) => entry.pluginId === plugin.id); const policyEntry = entries[normalizePluginPolicyId(plugin.id)]; const shapeSummary = buildPluginShapeSummary({ plugin, report }); const shape = shapeSummary.shape; const gatewayMethods = (report.gatewayMethodDescriptors ?? []).filter((descriptor) => descriptor.owner.kind === "plugin" && descriptor.owner.pluginId === plugin.id).map((descriptor) => descriptor.name); let mcpServers = []; if (plugin.rootDir) { const mcpSupport = plugin.format === "bundle" && plugin.bundleFormat ? inspectBundleMcpRuntimeSupport({ pluginId: plugin.id, rootDir: plugin.rootDir, bundleFormat: plugin.bundleFormat }) : plugin.mcpServers ? inspectNativePluginMcpRuntimeSupport({ rootDir: plugin.rootDir, mcpServers: plugin.mcpServers }) : void 0; if (mcpSupport) { const stdioServerNames = new Set(mcpSupport.stdioServerNames); mcpServers = [...mcpSupport.supportedServerNames.map((name) => ({ name, hasStdioTransport: stdioServerNames.has(name) })), ...mcpSupport.unsupportedServerNames.map((name) => ({ name, hasStdioTransport: false, unsupported: true }))]; } } let lspServers = []; if (plugin.format === "bundle" && plugin.bundleFormat && plugin.rootDir) { const lspSupport = inspectBundleLspRuntimeSupport({ pluginId: plugin.id, rootDir: plugin.rootDir, bundleFormat: plugin.bundleFormat }); lspServers = [...lspSupport.supportedServerNames.map((name) => ({ name, hasStdioTransport: true })), ...lspSupport.unsupportedServerNames.map((name) => ({ name, hasStdioTransport: false }))]; } const compatibility = buildCompatibilityNoticesForInspect({ plugin, shape, diagnostics }); return { workspaceDir: report.workspaceDir, plugin, shape, capabilityMode: shapeSummary.capabilityMode, capabilityCount: shapeSummary.capabilityCount, capabilities: shapeSummary.capabilities, typedHooks, customHooks, tools, commands: [...plugin.commands], cliCommands: [...plugin.cliCommands], services: [...plugin.services], gatewayDiscoveryServices: [...plugin.gatewayDiscoveryServiceIds], gatewayMethods, mcpServers, lspServers, httpRouteCount: plugin.httpRoutes, bundleCapabilities: plugin.bundleCapabilities ?? [], diagnostics, policy: { allowPromptInjection: policyEntry?.hooks?.allowPromptInjection, allowConversationAccess: policyEntry?.hooks?.allowConversationAccess, hookTimeoutMs: policyEntry?.hooks?.timeoutMs, hookTimeouts: policyEntry?.hooks?.timeouts ? { ...policyEntry.hooks.timeouts } : void 0, allowModelOverride: policyEntry?.subagent?.allowModelOverride, allowedModels: [...policyEntry?.subagent?.allowedModels ?? []], hasAllowedModelsConfig: policyEntry?.subagent?.hasAllowedModelsConfig === true }, compatibility }; } function buildAllPluginInspectReports(params = {}) { const context = resolvePluginInspectContext(params); return context.report.plugins.map((plugin) => buildPluginInspectRecord(plugin, context)); } function buildPluginCompatibilityWarnings(params) { return buildPluginCompatibilityNotices(params).map(formatPluginCompatibilityNotice); } function buildPluginCompatibilityNotices(params) { return buildAllPluginInspectReports(params).flatMap((inspect) => inspect.compatibility); } function buildPluginCompatibilitySnapshotNotices(params) { const report = buildPluginSnapshotReport(params); const context = resolvePluginRuntimeLoadContext(params); const runtimeRegistry = resolveCompatibleRuntimePluginRegistry(buildPluginRuntimeLoadOptions(context)); const registeredPlugins = new Map(runtimeRegistry?.plugins.map((plugin) => [plugin.id, plugin])); const registrationReport = runtimeRegistry ? { ...report, ...runtimeRegistry, workspaceDir: report.workspaceDir, plugins: report.plugins.map((plugin) => ({ ...plugin, ...registeredPlugins.get(plugin.id), imported: plugin.imported })) } : report; return buildPluginCompatibilityNotices({ ...params, report: registrationReport }); } //#endregion export { buildPluginDiagnosticsReport as a, buildPluginCompatibilityWarnings as i, buildPluginCompatibilityNotices as n, buildPluginInspectReport as o, buildPluginCompatibilitySnapshotNotices as r, buildPluginSnapshotReport as s, buildAllPluginInspectReports as t };