Reduce boilerplate.

This commit is contained in:
Christian Gunderman
2026-03-06 13:48:40 -08:00
parent 9a71caa781
commit 489e7bfbef
21 changed files with 230 additions and 151 deletions
@@ -52,15 +52,18 @@ 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:
case 'allow':
// Directly emit the response instead of recursive publish
this.emitMessage({
type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
@@ -69,6 +72,7 @@ export class MessageBus extends EventEmitter {
});
break;
case PolicyDecision.DENY:
case 'deny':
// Emit both rejection and response messages
this.emitMessage({
type: MessageBusType.TOOL_POLICY_REJECTION,
@@ -81,6 +85,7 @@ export class MessageBus extends EventEmitter {
});
break;
case PolicyDecision.ASK_USER:
case 'ask_user':
// Pass through to UI for user confirmation if any listeners exist.
// If no listeners are registered (e.g., headless/ACP flows),
// immediately request user confirmation to avoid long timeouts.
@@ -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 {