Skip to content

Add per-agent toggle to disable HITL approval notification emails #146

Description

@jiashuoz

Problem

When an agent has hitl_enabled: true, every pending_approval send fires an approval-notification email to the account owner via internal/hitlnotify/notifier.go. There is no way to opt out short of disabling HITL entirely.

This is painful in a few real cases:

  • E2E / load testing. During a prod test session, ~70 pending sends produced ~70 notification emails to the owner's inbox. The "queue then reject" pattern is not safe for testing because the notification already left by the time /messages/{id}/reject is called.
  • Dashboard-only reviewers. Some operators watch the dashboard live (or have a Slack integration polling pending messages) and don't want their inbox to fill up.
  • Programmatic approval flows. Agents whose approvals are driven by API/CLI/webhook callers don't need the magic-link email — the link goes unused.

Proposed solution

Add a per-agent boolean hitl_notify_email (default true to preserve existing behavior). When false, the HITL gate skips the call to Notifier.NotifyPendingApproval for that agent. All other HITL paths (dashboard view, CLI approve/reject, /messages/{id}/approve|reject, TTL expiration worker) remain unchanged.

Per-agent matches the existing HITL granularity (hitl_enabled, hitl_expiration_action, hitl_ttl_seconds) and is the simplest mental model for users.

Implementation sketch

  • Migration: ALTER TABLE agents ADD COLUMN IF NOT EXISTS hitl_notify_email BOOL NOT NULL DEFAULT TRUE; (idempotent, non-destructive — safe per the migration guidelines in CLAUDE.md)
  • Add the field to RegisterAgentRequest, UpdateAgentRequest, and Agent response with swag annotations
  • Branch in the HITL gate (where Notifier.NotifyPendingApproval is currently called) to skip when the agent's flag is false
  • make generate to regen TS + Python SDK types
  • CLI: surface as --no-notify on the relevant commands (or part of agents update)
  • Web: add a checkbox to the agent's HITL settings panel

Tradeoff to document

If a user disables notifications and stops watching the dashboard, pending messages will silently expire and act per hitl_expiration_action (approve or reject). The API description for hitl_notify_email should call this out.

Alternative considered

A per-request header override (X-E2A-Skip-Notification: 1 on /send) is more flexible but adds API surface for a niche case. Per-agent boolean covers all the use cases above with less complexity.

Out of scope

  • Per-recipient notification rules (deferred)
  • Notification channels other than email (Slack, webhook) — separate feature

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions