openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
425 lines (424 loc) • 16.9 kB
JavaScript
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 };