fix(hooks): support 'ask' decision for BeforeTool hooks (#21146)

This commit is contained in:
Christian Gunderman
2026-03-21 03:52:39 +00:00
committed by GitHub
parent d3766875f8
commit d1dc4902fd
32 changed files with 1016 additions and 117 deletions
@@ -83,13 +83,15 @@ export class MessageBus extends EventEmitter {
}
if (message.type === MessageBusType.TOOL_CONFIRMATION_REQUEST) {
const { decision } = await this.policyEngine.check(
const { decision: policyDecision } = await this.policyEngine.check(
message.toolCall,
message.serverName,
message.toolAnnotations,
message.subagent,
);
const decision = message.forcedDecision ?? policyDecision;
switch (decision) {
case PolicyDecision.ALLOW:
// Directly emit the response instead of recursive publish
@@ -46,6 +46,10 @@ export interface ToolConfirmationRequest {
* Optional rich details for the confirmation UI (diffs, counts, etc.)
*/
details?: SerializableConfirmationDetails;
/**
* Optional decision to force for this tool call, bypassing the policy engine.
*/
forcedDecision?: 'allow' | 'deny' | 'ask_user';
}
export interface ToolConfirmationResponse {
@@ -76,12 +80,14 @@ export type SerializableConfirmationDetails =
| {
type: 'info';
title: string;
systemMessage?: string;
prompt: string;
urls?: string[];
}
| {
type: 'edit';
title: string;
systemMessage?: string;
fileName: string;
filePath: string;
fileDiff: string;
@@ -92,6 +98,7 @@ export type SerializableConfirmationDetails =
| {
type: 'exec';
title: string;
systemMessage?: string;
command: string;
rootCommand: string;
rootCommands: string[];
@@ -100,6 +107,7 @@ export type SerializableConfirmationDetails =
| {
type: 'mcp';
title: string;
systemMessage?: string;
serverName: string;
toolName: string;
toolDisplayName: string;
@@ -110,11 +118,13 @@ export type SerializableConfirmationDetails =
| {
type: 'ask_user';
title: string;
systemMessage?: string;
questions: Question[];
}
| {
type: 'exit_plan_mode';
title: string;
systemMessage?: string;
planPath: string;
};