Fix bug where plugin hooks register but do not fire

This commit is contained in:
WallaceSociety 2026-01-29 06:35:26 -05:00
parent c41ea252b0
commit f5bedd1736
3 changed files with 58 additions and 23 deletions

View File

@ -29,9 +29,9 @@ export function initializeGlobalHookRunner(registry: PluginRegistry): void {
catchErrors: true,
});
const hookCount = registry.hooks.length;
if (hookCount > 0) {
log.info(`hook runner initialized with ${hookCount} registered hooks`);
const typedHookCount = registry.typedHooks.length;
if (typedHookCount > 0) {
log.info(`hook runner initialized with ${typedHookCount} registered hooks`);
}
}

View File

@ -7,26 +7,27 @@ import type {
} from "../gateway/server-methods/types.js";
import { registerInternalHook } from "../hooks/internal-hooks.js";
import { resolveUserPath } from "../utils.js";
import type {
MoltbotPluginApi,
MoltbotPluginChannelRegistration,
MoltbotPluginCliRegistrar,
MoltbotPluginCommandDefinition,
MoltbotPluginHttpHandler,
MoltbotPluginHttpRouteHandler,
MoltbotPluginHookOptions,
ProviderPlugin,
MoltbotPluginService,
MoltbotPluginToolContext,
MoltbotPluginToolFactory,
PluginConfigUiHint,
PluginDiagnostic,
PluginLogger,
PluginOrigin,
PluginKind,
PluginHookName,
PluginHookHandlerMap,
PluginHookRegistration as TypedPluginHookRegistration,
import {
TYPED_HOOK_NAMES,
type MoltbotPluginApi,
type MoltbotPluginChannelRegistration,
type MoltbotPluginCliRegistrar,
type MoltbotPluginCommandDefinition,
type MoltbotPluginHttpHandler,
type MoltbotPluginHttpRouteHandler,
type MoltbotPluginHookOptions,
type ProviderPlugin,
type MoltbotPluginService,
type MoltbotPluginToolContext,
type MoltbotPluginToolFactory,
type PluginConfigUiHint,
type PluginDiagnostic,
type PluginLogger,
type PluginOrigin,
type PluginKind,
type PluginHookName,
type PluginHookHandlerMap,
type PluginHookRegistration as TypedPluginHookRegistration,
} from "./types.js";
import { registerPluginCommand } from "./commands.js";
import type { PluginRuntime } from "./runtime/types.js";
@ -252,6 +253,22 @@ export function createPluginRegistry(registryParams: PluginRegistryParams) {
source: record.source,
});
// Bridge to typed hooks: if any event matches a PluginHookName, also register
// in typedHooks so the hook runner can find it. This allows plugins to use
// either api.registerHook() or api.on() for typed hooks like message_received.
for (const event of normalizedEvents) {
if (TYPED_HOOK_NAMES.has(event as PluginHookName)) {
registry.typedHooks.push({
pluginId: record.id,
hookName: event as PluginHookName,
handler: handler as unknown as PluginHookHandlerMap[PluginHookName],
priority: opts?.priority,
source: record.source,
} as TypedPluginHookRegistration);
record.hookCount += 1;
}
}
const hookSystemEnabled = config?.hooks?.internal?.enabled === true;
if (!hookSystemEnabled || opts?.register === false) {
return;

View File

@ -81,6 +81,7 @@ export type MoltbotPluginHookOptions = {
name?: string;
description?: string;
register?: boolean;
priority?: number;
};
export type ProviderAuthKind = "oauth" | "api_key" | "token" | "device_code" | "custom";
@ -302,6 +303,23 @@ export type PluginHookName =
| "gateway_start"
| "gateway_stop";
export const TYPED_HOOK_NAMES: Set<PluginHookName> = new Set<PluginHookName>([
"before_agent_start",
"agent_end",
"before_compaction",
"after_compaction",
"message_received",
"message_sending",
"message_sent",
"before_tool_call",
"after_tool_call",
"tool_result_persist",
"session_start",
"session_end",
"gateway_start",
"gateway_stop",
]);
// Agent context shared across agent hooks
export type PluginHookAgentContext = {
agentId?: string;