feat(core): wire up UI for ASK_USER policy decisions in message bus (#10630)

This commit is contained in:
Allen Hutchison
2025-10-15 09:39:41 -07:00
committed by GitHub
parent 8a937ebf8b
commit b8df8b2ab8
10 changed files with 431 additions and 99 deletions
+28 -6
View File
@@ -15,6 +15,7 @@ import {
Kind,
ToolConfirmationOutcome,
} from './tools.js';
import type { MessageBus } from '../confirmation-bus/message-bus.js';
import { ToolErrorType } from './tool-error.js';
import { getErrorMessage } from '../utils/errors.js';
import type { Config } from '../config/config.js';
@@ -107,8 +108,9 @@ class WebFetchToolInvocation extends BaseToolInvocation<
constructor(
private readonly config: Config,
params: WebFetchToolParams,
messageBus?: MessageBus,
) {
super(params);
super(params, messageBus);
}
private async executeFallback(signal: AbortSignal): Promise<ToolResult> {
@@ -181,9 +183,22 @@ ${textContent}
return `Processing URLs and instructions from prompt: "${displayPrompt}"`;
}
override async shouldConfirmExecute(): Promise<
ToolCallConfirmationDetails | false
> {
override async shouldConfirmExecute(
abortSignal: AbortSignal,
): Promise<ToolCallConfirmationDetails | false> {
// Try message bus confirmation first if available
if (this.messageBus) {
const decision = await this.getMessageBusDecision(abortSignal);
if (decision === 'ALLOW') {
return false; // No confirmation needed
}
if (decision === 'DENY') {
throw new Error('Tool execution denied by policy.');
}
// if 'ASK_USER', fall through to legacy logic
}
// Legacy confirmation flow (no message bus OR policy decision was ASK_USER)
if (this.config.getApprovalMode() === ApprovalMode.AUTO_EDIT) {
return false;
}
@@ -366,7 +381,10 @@ export class WebFetchTool extends BaseDeclarativeTool<
> {
static readonly Name: string = 'web_fetch';
constructor(private readonly config: Config) {
constructor(
private readonly config: Config,
messageBus?: MessageBus,
) {
super(
WebFetchTool.Name,
'WebFetch',
@@ -383,6 +401,9 @@ export class WebFetchTool extends BaseDeclarativeTool<
required: ['prompt'],
type: 'object',
},
true, // isOutputMarkdown
false, // canUpdateOutput
messageBus,
);
const proxy = config.getProxy();
if (proxy) {
@@ -412,7 +433,8 @@ export class WebFetchTool extends BaseDeclarativeTool<
protected createInvocation(
params: WebFetchToolParams,
messageBus?: MessageBus,
): ToolInvocation<WebFetchToolParams, ToolResult> {
return new WebFetchToolInvocation(this.config, params);
return new WebFetchToolInvocation(this.config, params, messageBus);
}
}