Skip to content

sub(#248) Phase 2: Confirmation dialog UI and settings #270

@mmogr

Description

@mmogr

Parent: #248 — Tool confirmation/consent flow

Goal

Build the user-facing confirmation dialog that appears when a tool requires approval, and a settings page to configure per-tool consent preferences.

Background

Phase 1 (#269) adds the metadata and pause mechanism. This phase creates the UI components.

Implementation

1. ToolConfirmationDialog component

// src/components/ToolConfirmationDialog.tsx
interface ToolConfirmationDialogProps {
  toolCall: ToolCall;
  metadata: ToolMetadata;
  onApprove: () => void;
  onDeny: () => void;
  onAlwaysAllow: () => void;  // "Don't ask again for this tool"
}

function ToolConfirmationDialog({ toolCall, metadata, onApprove, onDeny, onAlwaysAllow }: Props) {
  return (
    <Dialog>
      <DialogHeader>
        <RiskBadge level={metadata.riskLevel} />
        <span>Tool: {toolCall.function.name}</span>
      </DialogHeader>
      <DialogBody>
        <p>{metadata.impactDescription || toolCall.function.name + ' wants to execute'}</p>
        <ArgumentsPreview args={toolCall.function.arguments} />
      </DialogBody>
      <DialogFooter>
        <Button variant="ghost" onClick={onDeny}>Deny</Button>
        <Button variant="outline" onClick={onAlwaysAllow}>Always Allow</Button>
        <Button variant="primary" onClick={onApprove}>Approve</Button>
      </DialogFooter>
    </Dialog>
  );
}

2. Risk level visual indicators

function RiskBadge({ level }: { level: 'safe' | 'moderate' | 'dangerous' }) {
  const config = {
    safe: { color: 'green', icon: '✓', label: 'Safe' },
    moderate: { color: 'yellow', icon: '⚠', label: 'Moderate' },
    dangerous: { color: 'red', icon: '⚡', label: 'Caution' },
  };
  // ...
}

3. Tool consent settings page

Add a section to settings where users can:

  • View all registered tools with their risk levels
  • Toggle requiresConfirmation per-tool
  • Set global policy: "Always ask" / "Ask for moderate+" / "Ask for dangerous only" / "Never ask"
  • Persist preferences in settings store

4. Wire confirmation dialog into chat

Connect the dialog to the onToolConfirmationRequired callback from the agentic loop:

// In useGglibRuntime.ts
const handleConfirmation = useCallback((toolCall, metadata) => {
  return new Promise<boolean>((resolve) => {
    setConfirmationState({ toolCall, metadata, resolve });
  });
}, []);

Files to Create/Modify

File Action
src/components/ToolConfirmationDialog.tsx Create — confirmation dialog component
src/components/RiskBadge.tsx Create — risk level visual indicator
src/pages/Settings/ToolSettings.tsx Create — tool consent management UI
src/hooks/useGglibRuntime.ts Wire confirmation callback
src/config/ Persist per-tool consent preferences

Acceptance Criteria

  • Confirmation dialog appears when agentic loop hits a requiresConfirmation tool
  • Dialog shows tool name, arguments preview, risk level badge
  • User can Approve, Deny, or "Always Allow" (persist preference)
  • "Always Allow" persisted per-tool in settings
  • Settings page shows all tools with risk levels and confirmation toggles
  • Global consent policy configurable (always/moderate+/dangerous/never)
  • Dialog is keyboard-accessible (Enter=Approve, Escape=Deny)
  • Chat conversation continues correctly after both Approve and Deny

Metadata

Metadata

Assignees

No one assigned

    Labels

    component: frontendReact/TypeScript UIpriority: lowNice to havesize: m4-8 hours (half to full day)type: featureNew functionality or enhancementuxUser experience improvements

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions