feat(core): Introduce message bus for tool execution confirmation (#11544)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
Allen Hutchison
2025-10-24 13:04:40 -07:00
committed by GitHub
parent 63a90836fe
commit b188a51c32
15 changed files with 224 additions and 92 deletions
+29 -17
View File
@@ -104,25 +104,37 @@ export abstract class BaseToolInvocation<
}
if (decision === 'ASK_USER') {
const confirmationDetails: ToolCallConfirmationDetails = {
type: 'info',
title: `Confirm: ${this._toolDisplayName || this._toolName}`,
prompt: this.getDescription(),
onConfirm: async (outcome: ToolConfirmationOutcome) => {
if (outcome === ToolConfirmationOutcome.ProceedAlways) {
if (this.messageBus && this._toolName) {
this.messageBus.publish({
type: MessageBusType.UPDATE_POLICY,
toolName: this._toolName,
});
}
}
},
};
return confirmationDetails;
return this.getConfirmationDetails(abortSignal);
}
}
return false;
// When no message bus, use default confirmation flow
return this.getConfirmationDetails(abortSignal);
}
/**
* Subclasses should override this method to provide custom confirmation UI
* when the policy engine's decision is 'ASK_USER'.
* The base implementation provides a generic confirmation prompt.
*/
protected async getConfirmationDetails(
_abortSignal: AbortSignal,
): Promise<ToolCallConfirmationDetails | false> {
const confirmationDetails: ToolCallConfirmationDetails = {
type: 'info',
title: `Confirm: ${this._toolDisplayName || this._toolName}`,
prompt: this.getDescription(),
onConfirm: async (outcome: ToolConfirmationOutcome) => {
if (outcome === ToolConfirmationOutcome.ProceedAlways) {
if (this.messageBus && this._toolName) {
this.messageBus.publish({
type: MessageBusType.UPDATE_POLICY,
toolName: this._toolName,
});
}
}
},
};
return confirmationDetails;
}
protected getMessageBusDecision(