fix: capture sendFinalReply return value and document fail-open semantics

Address bot review feedback:
- Use actual sendFinalReply() return for queuedFinal instead of Boolean proxy
- Add JSDoc note about fail-open error semantics for security plugins

Made-with: Cursor
This commit is contained in:
李玉涵 2026-03-12 03:40:30 +08:00
parent e84a11411a
commit fafeff9d19
2 changed files with 9 additions and 7 deletions

View File

@ -225,14 +225,11 @@ export async function dispatchReplyFromConfig(params: {
toPluginMessageContext(hookContext), toPluginMessageContext(hookContext),
); );
if (beforeDispatchResult?.block) { if (beforeDispatchResult?.block) {
if (beforeDispatchResult.replyText) { const queuedFinal = beforeDispatchResult.replyText
dispatcher.sendFinalReply({ text: beforeDispatchResult.replyText }); ? dispatcher.sendFinalReply({ text: beforeDispatchResult.replyText })
} : false;
recordProcessed("skipped", { reason: "before_dispatch_blocked" }); recordProcessed("skipped", { reason: "before_dispatch_blocked" });
return { return { queuedFinal, counts: dispatcher.getQueuedCounts() };
queuedFinal: Boolean(beforeDispatchResult.replyText),
counts: dispatcher.getQueuedCounts(),
};
} }
} }

View File

@ -439,6 +439,11 @@ export function createHookRunner(registry: PluginRegistry, options: HookRunnerOp
* Allows plugins to block the entire message dispatch before LLM invocation * Allows plugins to block the entire message dispatch before LLM invocation
* and optionally send a reply text directly to the user. * and optionally send a reply text directly to the user.
* Runs sequentially first handler that returns { block: true } wins. * Runs sequentially first handler that returns { block: true } wins.
*
* **Error semantics:** Like all hooks, errors are caught and logged when
* `catchErrors` is true (the default). This means a throwing handler
* results in permit-by-default (fail-open). Security-critical plugins
* should handle errors internally to implement fail-closed behavior.
*/ */
async function runBeforeDispatch( async function runBeforeDispatch(
event: PluginHookBeforeDispatchEvent, event: PluginHookBeforeDispatchEvent,