mirror of https://github.com/openclaw/openclaw.git
Plugins: extract registry registration actions
This commit is contained in:
parent
41acacbd02
commit
4ca9cd7e5e
|
|
@ -0,0 +1,69 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { createEmptyPluginRegistry, type PluginRecord } from "../plugins/registry.js";
|
||||
import { createExtensionHostPluginRegistrationActions } from "./plugin-registry-registrations.js";
|
||||
|
||||
function createRecord(): PluginRecord {
|
||||
return {
|
||||
id: "demo",
|
||||
name: "Demo",
|
||||
source: "/plugins/demo.ts",
|
||||
origin: "workspace",
|
||||
enabled: true,
|
||||
status: "loaded",
|
||||
toolNames: [],
|
||||
hookNames: [],
|
||||
channelIds: [],
|
||||
providerIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
httpRoutes: 0,
|
||||
hookCount: 0,
|
||||
configSchema: false,
|
||||
};
|
||||
}
|
||||
|
||||
describe("extension host plugin registry registrations", () => {
|
||||
it("reports gateway-method collisions against core methods", () => {
|
||||
const registry = createEmptyPluginRegistry();
|
||||
const actions = createExtensionHostPluginRegistrationActions({
|
||||
registry,
|
||||
coreGatewayMethods: new Set(["ping"]),
|
||||
pushDiagnostic: (diag) => {
|
||||
registry.diagnostics.push(diag);
|
||||
},
|
||||
});
|
||||
|
||||
actions.registerGatewayMethod(createRecord(), "ping", (() => {}) as never);
|
||||
|
||||
expect(registry.gatewayHandlers.ping).toBeUndefined();
|
||||
expect(registry.diagnostics).toContainEqual(
|
||||
expect.objectContaining({
|
||||
level: "error",
|
||||
pluginId: "demo",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("reports invalid context-engine registrations through the host-owned action helper", () => {
|
||||
const registry = createEmptyPluginRegistry();
|
||||
const actions = createExtensionHostPluginRegistrationActions({
|
||||
registry,
|
||||
coreGatewayMethods: new Set(),
|
||||
pushDiagnostic: (diag) => {
|
||||
registry.diagnostics.push(diag);
|
||||
},
|
||||
});
|
||||
|
||||
actions.registerContextEngine(createRecord(), " ", (() => ({})) as never);
|
||||
|
||||
expect(registry.diagnostics).toContainEqual(
|
||||
expect.objectContaining({
|
||||
level: "error",
|
||||
pluginId: "demo",
|
||||
message: "context engine registration missing id",
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,338 @@
|
|||
import type { AnyAgentTool } from "../agents/tools/common.js";
|
||||
import type { ChannelPlugin } from "../channels/plugins/types.js";
|
||||
import { registerContextEngine as registerLegacyContextEngine } from "../context-engine/registry.js";
|
||||
import type { GatewayRequestHandler } from "../gateway/server-methods/types.js";
|
||||
import { registerInternalHook } from "../hooks/internal-hooks.js";
|
||||
import type { PluginRecord, PluginRegistry } from "../plugins/registry.js";
|
||||
import type {
|
||||
PluginHookHandlerMap,
|
||||
PluginHookName,
|
||||
OpenClawPluginApi,
|
||||
OpenClawPluginChannelRegistration,
|
||||
OpenClawPluginCliRegistrar,
|
||||
OpenClawPluginHookOptions,
|
||||
OpenClawPluginHttpRouteParams,
|
||||
OpenClawPluginService,
|
||||
OpenClawPluginToolFactory,
|
||||
PluginHookRegistration as TypedPluginHookRegistration,
|
||||
} from "../plugins/types.js";
|
||||
import {
|
||||
applyExtensionHostTypedHookPolicy,
|
||||
bridgeExtensionHostLegacyHooks,
|
||||
} from "./hook-compat.js";
|
||||
import { pushExtensionHostRegistryDiagnostic } from "./plugin-registry-compat.js";
|
||||
import {
|
||||
addExtensionChannelRegistration,
|
||||
addExtensionCliRegistration,
|
||||
addExtensionContextEngineRegistration,
|
||||
addExtensionGatewayMethodRegistration,
|
||||
addExtensionLegacyHookRegistration,
|
||||
addExtensionHttpRouteRegistration,
|
||||
addExtensionServiceRegistration,
|
||||
addExtensionToolRegistration,
|
||||
addExtensionTypedHookRegistration,
|
||||
} from "./registry-writes.js";
|
||||
import {
|
||||
resolveExtensionChannelRegistration,
|
||||
resolveExtensionCliRegistration,
|
||||
resolveExtensionContextEngineRegistration,
|
||||
resolveExtensionGatewayMethodRegistration,
|
||||
resolveExtensionLegacyHookRegistration,
|
||||
resolveExtensionHttpRouteRegistration,
|
||||
resolveExtensionServiceRegistration,
|
||||
resolveExtensionToolRegistration,
|
||||
resolveExtensionTypedHookRegistration,
|
||||
} from "./runtime-registrations.js";
|
||||
|
||||
export type PluginTypedHookPolicy = {
|
||||
allowPromptInjection?: boolean;
|
||||
};
|
||||
|
||||
export function createExtensionHostPluginRegistrationActions(params: {
|
||||
registry: PluginRegistry;
|
||||
coreGatewayMethods: Set<string>;
|
||||
}) {
|
||||
const { registry, coreGatewayMethods } = params;
|
||||
|
||||
const registerTool = (
|
||||
record: PluginRecord,
|
||||
tool: AnyAgentTool | OpenClawPluginToolFactory,
|
||||
opts?: { name?: string; names?: string[]; optional?: boolean },
|
||||
) => {
|
||||
const result = resolveExtensionToolRegistration({
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
tool,
|
||||
opts,
|
||||
});
|
||||
addExtensionToolRegistration({ registry, record, names: result.names, entry: result.entry });
|
||||
};
|
||||
|
||||
const registerHook = (
|
||||
record: PluginRecord,
|
||||
events: string | string[],
|
||||
handler: Parameters<typeof registerInternalHook>[1],
|
||||
opts: OpenClawPluginHookOptions | undefined,
|
||||
config: OpenClawPluginApi["config"],
|
||||
) => {
|
||||
const normalized = resolveExtensionLegacyHookRegistration({
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
events,
|
||||
handler,
|
||||
opts,
|
||||
});
|
||||
if (!normalized.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "warn",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: normalized.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
addExtensionLegacyHookRegistration({
|
||||
registry,
|
||||
record,
|
||||
hookName: normalized.hookName,
|
||||
entry: normalized.entry,
|
||||
events: normalized.events,
|
||||
});
|
||||
|
||||
bridgeExtensionHostLegacyHooks({
|
||||
events: normalized.events,
|
||||
handler,
|
||||
hookSystemEnabled: config?.hooks?.internal?.enabled === true,
|
||||
register: opts?.register,
|
||||
registerHook: registerInternalHook,
|
||||
});
|
||||
};
|
||||
|
||||
const registerGatewayMethod = (
|
||||
record: PluginRecord,
|
||||
method: string,
|
||||
handler: GatewayRequestHandler,
|
||||
) => {
|
||||
const result = resolveExtensionGatewayMethodRegistration({
|
||||
existing: registry.gatewayHandlers,
|
||||
coreGatewayMethods,
|
||||
method,
|
||||
handler,
|
||||
});
|
||||
if (!result.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "error",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: result.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
addExtensionGatewayMethodRegistration({
|
||||
registry,
|
||||
record,
|
||||
method: result.method,
|
||||
handler: result.handler,
|
||||
});
|
||||
};
|
||||
|
||||
const registerHttpRoute = (record: PluginRecord, route: OpenClawPluginHttpRouteParams) => {
|
||||
const result = resolveExtensionHttpRouteRegistration({
|
||||
existing: registry.httpRoutes,
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
route,
|
||||
});
|
||||
if (!result.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: result.message === "http route registration missing path" ? "warn" : "error",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: result.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (result.action === "replace") {
|
||||
addExtensionHttpRouteRegistration({
|
||||
registry,
|
||||
record,
|
||||
action: "replace",
|
||||
existingIndex: result.existingIndex,
|
||||
entry: result.entry,
|
||||
});
|
||||
return;
|
||||
}
|
||||
addExtensionHttpRouteRegistration({
|
||||
registry,
|
||||
record,
|
||||
action: "append",
|
||||
entry: result.entry,
|
||||
});
|
||||
};
|
||||
|
||||
const registerChannel = (
|
||||
record: PluginRecord,
|
||||
registration: OpenClawPluginChannelRegistration | ChannelPlugin,
|
||||
) => {
|
||||
const result = resolveExtensionChannelRegistration({
|
||||
existing: registry.channels,
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
registration,
|
||||
});
|
||||
if (!result.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "error",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: result.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
addExtensionChannelRegistration({
|
||||
registry,
|
||||
record,
|
||||
channelId: result.channelId,
|
||||
entry: result.entry,
|
||||
});
|
||||
};
|
||||
|
||||
const registerCli = (
|
||||
record: PluginRecord,
|
||||
registrar: OpenClawPluginCliRegistrar,
|
||||
opts?: { commands?: string[] },
|
||||
) => {
|
||||
const result = resolveExtensionCliRegistration({
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
registrar,
|
||||
opts,
|
||||
});
|
||||
addExtensionCliRegistration({
|
||||
registry,
|
||||
record,
|
||||
commands: result.commands,
|
||||
entry: result.entry,
|
||||
});
|
||||
};
|
||||
|
||||
const registerService = (record: PluginRecord, service: OpenClawPluginService) => {
|
||||
const result = resolveExtensionServiceRegistration({
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
service,
|
||||
});
|
||||
if (!result.ok) {
|
||||
return;
|
||||
}
|
||||
addExtensionServiceRegistration({
|
||||
registry,
|
||||
record,
|
||||
serviceId: result.serviceId,
|
||||
entry: result.entry,
|
||||
});
|
||||
};
|
||||
|
||||
const registerTypedHook = <K extends PluginHookName>(
|
||||
record: PluginRecord,
|
||||
hookName: K,
|
||||
handler: PluginHookHandlerMap[K],
|
||||
opts?: { priority?: number },
|
||||
policy?: PluginTypedHookPolicy,
|
||||
) => {
|
||||
const normalized = resolveExtensionTypedHookRegistration({
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
hookName,
|
||||
handler,
|
||||
priority: opts?.priority,
|
||||
});
|
||||
if (!normalized.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "warn",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: normalized.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const policyResult = applyExtensionHostTypedHookPolicy({
|
||||
hookName: normalized.hookName,
|
||||
handler,
|
||||
policy,
|
||||
blockedMessage: `typed hook "${normalized.hookName}" blocked by plugins.entries.${record.id}.hooks.allowPromptInjection=false`,
|
||||
constrainedMessage: `typed hook "${normalized.hookName}" prompt fields constrained by plugins.entries.${record.id}.hooks.allowPromptInjection=false`,
|
||||
});
|
||||
if (!policyResult.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "warn",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: policyResult.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (policyResult.warningMessage) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "warn",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: policyResult.warningMessage,
|
||||
});
|
||||
}
|
||||
addExtensionTypedHookRegistration({
|
||||
registry,
|
||||
record,
|
||||
entry: {
|
||||
...normalized.entry,
|
||||
pluginId: record.id,
|
||||
hookName: normalized.hookName,
|
||||
handler: policyResult.entryHandler,
|
||||
} as TypedPluginHookRegistration,
|
||||
});
|
||||
};
|
||||
|
||||
const registerContextEngine = (
|
||||
record: PluginRecord,
|
||||
engineId: string,
|
||||
factory: Parameters<typeof registerLegacyContextEngine>[1],
|
||||
) => {
|
||||
const result = resolveExtensionContextEngineRegistration({
|
||||
engineId,
|
||||
factory,
|
||||
});
|
||||
if (!result.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "error",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: result.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
addExtensionContextEngineRegistration({
|
||||
entry: result.entry,
|
||||
registerEngine: registerLegacyContextEngine,
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
registerTool,
|
||||
registerHook,
|
||||
registerGatewayMethod,
|
||||
registerHttpRoute,
|
||||
registerChannel,
|
||||
registerCli,
|
||||
registerService,
|
||||
registerTypedHook,
|
||||
registerContextEngine,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,62 +1,23 @@
|
|||
import type { AnyAgentTool } from "../agents/tools/common.js";
|
||||
import type { ChannelPlugin } from "../channels/plugins/types.js";
|
||||
import { registerContextEngine } from "../context-engine/registry.js";
|
||||
import {
|
||||
applyExtensionHostTypedHookPolicy,
|
||||
bridgeExtensionHostLegacyHooks,
|
||||
} from "../extension-host/hook-compat.js";
|
||||
import { createExtensionHostPluginApi } from "../extension-host/plugin-api.js";
|
||||
import {
|
||||
addExtensionChannelRegistration,
|
||||
addExtensionCliRegistration,
|
||||
addExtensionCommandRegistration,
|
||||
addExtensionContextEngineRegistration,
|
||||
addExtensionGatewayMethodRegistration,
|
||||
addExtensionLegacyHookRegistration,
|
||||
addExtensionHttpRouteRegistration,
|
||||
addExtensionProviderRegistration,
|
||||
addExtensionServiceRegistration,
|
||||
addExtensionToolRegistration,
|
||||
addExtensionTypedHookRegistration,
|
||||
} from "../extension-host/registry-writes.js";
|
||||
import {
|
||||
resolveExtensionChannelRegistration,
|
||||
resolveExtensionCliRegistration,
|
||||
resolveExtensionContextEngineRegistration,
|
||||
resolveExtensionGatewayMethodRegistration,
|
||||
resolveExtensionLegacyHookRegistration,
|
||||
resolveExtensionHttpRouteRegistration,
|
||||
resolveExtensionServiceRegistration,
|
||||
resolveExtensionToolRegistration,
|
||||
resolveExtensionTypedHookRegistration,
|
||||
} from "../extension-host/runtime-registrations.js";
|
||||
import type { GatewayRequestHandler } from "../gateway/server-methods/types.js";
|
||||
import { registerInternalHook } from "../hooks/internal-hooks.js";
|
||||
import type { PluginRecord, PluginRegistry, PluginRegistryParams } from "../plugins/registry.js";
|
||||
import type {
|
||||
PluginDiagnostic,
|
||||
PluginHookHandlerMap,
|
||||
PluginHookName,
|
||||
OpenClawPluginApi,
|
||||
OpenClawPluginChannelRegistration,
|
||||
OpenClawPluginCliRegistrar,
|
||||
OpenClawPluginCommandDefinition,
|
||||
OpenClawPluginHookOptions,
|
||||
OpenClawPluginHttpRouteParams,
|
||||
OpenClawPluginService,
|
||||
OpenClawPluginToolFactory,
|
||||
ProviderPlugin,
|
||||
PluginHookRegistration as TypedPluginHookRegistration,
|
||||
} from "../plugins/types.js";
|
||||
import { createExtensionHostPluginApi } from "./plugin-api.js";
|
||||
import {
|
||||
pushExtensionHostRegistryDiagnostic,
|
||||
resolveExtensionHostCommandCompatibility,
|
||||
resolveExtensionHostProviderCompatibility,
|
||||
} from "./plugin-registry-compat.js";
|
||||
|
||||
type PluginTypedHookPolicy = {
|
||||
allowPromptInjection?: boolean;
|
||||
};
|
||||
import {
|
||||
createExtensionHostPluginRegistrationActions,
|
||||
type PluginTypedHookPolicy,
|
||||
} from "./plugin-registry-registrations.js";
|
||||
import {
|
||||
addExtensionCommandRegistration,
|
||||
addExtensionProviderRegistration,
|
||||
} from "./registry-writes.js";
|
||||
|
||||
export function createExtensionHostPluginRegistry(params: {
|
||||
registry: PluginRegistry;
|
||||
|
|
@ -67,153 +28,10 @@ export function createExtensionHostPluginRegistry(params: {
|
|||
const pushDiagnostic = (diag: PluginDiagnostic) => {
|
||||
registry.diagnostics.push(diag);
|
||||
};
|
||||
|
||||
const registerTool = (
|
||||
record: PluginRecord,
|
||||
tool: AnyAgentTool | OpenClawPluginToolFactory,
|
||||
opts?: { name?: string; names?: string[]; optional?: boolean },
|
||||
) => {
|
||||
const result = resolveExtensionToolRegistration({
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
tool,
|
||||
opts,
|
||||
});
|
||||
addExtensionToolRegistration({ registry, record, names: result.names, entry: result.entry });
|
||||
};
|
||||
|
||||
const registerHook = (
|
||||
record: PluginRecord,
|
||||
events: string | string[],
|
||||
handler: Parameters<typeof registerInternalHook>[1],
|
||||
opts: OpenClawPluginHookOptions | undefined,
|
||||
config: OpenClawPluginApi["config"],
|
||||
) => {
|
||||
const normalized = resolveExtensionLegacyHookRegistration({
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
events,
|
||||
handler,
|
||||
opts,
|
||||
});
|
||||
if (!normalized.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "warn",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: normalized.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
addExtensionLegacyHookRegistration({
|
||||
registry,
|
||||
record,
|
||||
hookName: normalized.hookName,
|
||||
entry: normalized.entry,
|
||||
events: normalized.events,
|
||||
});
|
||||
|
||||
bridgeExtensionHostLegacyHooks({
|
||||
events: normalized.events,
|
||||
handler,
|
||||
hookSystemEnabled: config?.hooks?.internal?.enabled === true,
|
||||
register: opts?.register,
|
||||
registerHook: registerInternalHook,
|
||||
});
|
||||
};
|
||||
|
||||
const registerGatewayMethod = (
|
||||
record: PluginRecord,
|
||||
method: string,
|
||||
handler: GatewayRequestHandler,
|
||||
) => {
|
||||
const result = resolveExtensionGatewayMethodRegistration({
|
||||
existing: registry.gatewayHandlers,
|
||||
coreGatewayMethods,
|
||||
method,
|
||||
handler,
|
||||
});
|
||||
if (!result.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "error",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: result.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
addExtensionGatewayMethodRegistration({
|
||||
registry,
|
||||
record,
|
||||
method: result.method,
|
||||
handler: result.handler,
|
||||
});
|
||||
};
|
||||
|
||||
const registerHttpRoute = (record: PluginRecord, route: OpenClawPluginHttpRouteParams) => {
|
||||
const result = resolveExtensionHttpRouteRegistration({
|
||||
existing: registry.httpRoutes,
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
route,
|
||||
});
|
||||
if (!result.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: result.message === "http route registration missing path" ? "warn" : "error",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: result.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (result.action === "replace") {
|
||||
addExtensionHttpRouteRegistration({
|
||||
registry,
|
||||
record,
|
||||
action: "replace",
|
||||
existingIndex: result.existingIndex,
|
||||
entry: result.entry,
|
||||
});
|
||||
return;
|
||||
}
|
||||
addExtensionHttpRouteRegistration({
|
||||
registry,
|
||||
record,
|
||||
action: "append",
|
||||
entry: result.entry,
|
||||
});
|
||||
};
|
||||
|
||||
const registerChannel = (
|
||||
record: PluginRecord,
|
||||
registration: OpenClawPluginChannelRegistration | ChannelPlugin,
|
||||
) => {
|
||||
const result = resolveExtensionChannelRegistration({
|
||||
existing: registry.channels,
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
registration,
|
||||
});
|
||||
if (!result.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "error",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: result.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
addExtensionChannelRegistration({
|
||||
registry,
|
||||
record,
|
||||
channelId: result.channelId,
|
||||
entry: result.entry,
|
||||
});
|
||||
};
|
||||
const actions = createExtensionHostPluginRegistrationActions({
|
||||
registry,
|
||||
coreGatewayMethods,
|
||||
});
|
||||
|
||||
const registerProvider = (record: PluginRecord, provider: ProviderPlugin) => {
|
||||
const result = resolveExtensionHostProviderCompatibility({
|
||||
|
|
@ -232,42 +50,6 @@ export function createExtensionHostPluginRegistry(params: {
|
|||
});
|
||||
};
|
||||
|
||||
const registerCli = (
|
||||
record: PluginRecord,
|
||||
registrar: OpenClawPluginCliRegistrar,
|
||||
opts?: { commands?: string[] },
|
||||
) => {
|
||||
const result = resolveExtensionCliRegistration({
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
registrar,
|
||||
opts,
|
||||
});
|
||||
addExtensionCliRegistration({
|
||||
registry,
|
||||
record,
|
||||
commands: result.commands,
|
||||
entry: result.entry,
|
||||
});
|
||||
};
|
||||
|
||||
const registerService = (record: PluginRecord, service: OpenClawPluginService) => {
|
||||
const result = resolveExtensionServiceRegistration({
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
service,
|
||||
});
|
||||
if (!result.ok) {
|
||||
return;
|
||||
}
|
||||
addExtensionServiceRegistration({
|
||||
registry,
|
||||
record,
|
||||
serviceId: result.serviceId,
|
||||
entry: result.entry,
|
||||
});
|
||||
};
|
||||
|
||||
const registerCommand = (record: PluginRecord, command: OpenClawPluginCommandDefinition) => {
|
||||
const normalized = resolveExtensionHostCommandCompatibility({ registry, record, command });
|
||||
if (!normalized.ok) {
|
||||
|
|
@ -281,68 +63,6 @@ export function createExtensionHostPluginRegistry(params: {
|
|||
});
|
||||
};
|
||||
|
||||
const registerTypedHook = <K extends PluginHookName>(
|
||||
record: PluginRecord,
|
||||
hookName: K,
|
||||
handler: PluginHookHandlerMap[K],
|
||||
opts?: { priority?: number },
|
||||
policy?: PluginTypedHookPolicy,
|
||||
) => {
|
||||
const normalized = resolveExtensionTypedHookRegistration({
|
||||
ownerPluginId: record.id,
|
||||
ownerSource: record.source,
|
||||
hookName,
|
||||
handler,
|
||||
priority: opts?.priority,
|
||||
});
|
||||
if (!normalized.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "warn",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: normalized.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const policyResult = applyExtensionHostTypedHookPolicy({
|
||||
hookName: normalized.hookName,
|
||||
handler,
|
||||
policy,
|
||||
blockedMessage: `typed hook "${normalized.hookName}" blocked by plugins.entries.${record.id}.hooks.allowPromptInjection=false`,
|
||||
constrainedMessage: `typed hook "${normalized.hookName}" prompt fields constrained by plugins.entries.${record.id}.hooks.allowPromptInjection=false`,
|
||||
});
|
||||
if (!policyResult.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "warn",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: policyResult.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (policyResult.warningMessage) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "warn",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: policyResult.warningMessage,
|
||||
});
|
||||
}
|
||||
addExtensionTypedHookRegistration({
|
||||
registry,
|
||||
record,
|
||||
entry: {
|
||||
...normalized.entry,
|
||||
pluginId: record.id,
|
||||
hookName: normalized.hookName,
|
||||
handler: policyResult.entryHandler,
|
||||
} as TypedPluginHookRegistration,
|
||||
});
|
||||
};
|
||||
|
||||
const createApi = (
|
||||
record: PluginRecord,
|
||||
params: {
|
||||
|
|
@ -357,38 +77,20 @@ export function createExtensionHostPluginRegistry(params: {
|
|||
logger: registryParams.logger,
|
||||
config: params.config,
|
||||
pluginConfig: params.pluginConfig,
|
||||
registerTool: (tool, opts) => registerTool(record, tool, opts),
|
||||
registerTool: (tool, opts) => actions.registerTool(record, tool, opts),
|
||||
registerHook: (events, handler, opts) =>
|
||||
registerHook(record, events, handler, opts, params.config),
|
||||
registerHttpRoute: (routeParams) => registerHttpRoute(record, routeParams),
|
||||
registerChannel: (registration) => registerChannel(record, registration as never),
|
||||
actions.registerHook(record, events, handler, opts, params.config),
|
||||
registerHttpRoute: (routeParams) => actions.registerHttpRoute(record, routeParams),
|
||||
registerChannel: (registration) => actions.registerChannel(record, registration as never),
|
||||
registerProvider: (provider) => registerProvider(record, provider),
|
||||
registerGatewayMethod: (method, handler) => registerGatewayMethod(record, method, handler),
|
||||
registerCli: (registrar, opts) => registerCli(record, registrar, opts),
|
||||
registerService: (service) => registerService(record, service),
|
||||
registerGatewayMethod: (method, handler) =>
|
||||
actions.registerGatewayMethod(record, method, handler),
|
||||
registerCli: (registrar, opts) => actions.registerCli(record, registrar, opts),
|
||||
registerService: (service) => actions.registerService(record, service),
|
||||
registerCommand: (command) => registerCommand(record, command),
|
||||
registerContextEngine: (id, factory) => {
|
||||
const result = resolveExtensionContextEngineRegistration({
|
||||
engineId: id,
|
||||
factory,
|
||||
});
|
||||
if (!result.ok) {
|
||||
pushExtensionHostRegistryDiagnostic({
|
||||
registry,
|
||||
level: "error",
|
||||
pluginId: record.id,
|
||||
source: record.source,
|
||||
message: result.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
addExtensionContextEngineRegistration({
|
||||
entry: result.entry,
|
||||
registerEngine: registerContextEngine,
|
||||
});
|
||||
},
|
||||
registerContextEngine: (id, factory) => actions.registerContextEngine(record, id, factory),
|
||||
on: (hookName, handler, opts) =>
|
||||
registerTypedHook(record, hookName, handler, opts, params.hookPolicy),
|
||||
actions.registerTypedHook(record, hookName, handler, opts, params.hookPolicy),
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -396,14 +98,14 @@ export function createExtensionHostPluginRegistry(params: {
|
|||
registry,
|
||||
createApi,
|
||||
pushDiagnostic,
|
||||
registerTool,
|
||||
registerChannel,
|
||||
registerTool: actions.registerTool,
|
||||
registerChannel: actions.registerChannel,
|
||||
registerProvider,
|
||||
registerGatewayMethod,
|
||||
registerCli,
|
||||
registerService,
|
||||
registerGatewayMethod: actions.registerGatewayMethod,
|
||||
registerCli: actions.registerCli,
|
||||
registerService: actions.registerService,
|
||||
registerCommand,
|
||||
registerHook,
|
||||
registerTypedHook,
|
||||
registerHook: actions.registerHook,
|
||||
registerTypedHook: actions.registerTypedHook,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue