Draft: Deliver Duo flow callbacks via webhook adapter

What does this MR do?

Implements the delivery half of Duo flow callback hooks, following up on !247573 (merged) (registration-only): a client that registers a Ai::DuoWorkflows::FlowCallbackHook can now reference it via callback_hook_id when creating a flow, and receives signed flow.started, flow.completed, and flow.failed events instead of polling for status.

New pieces

  • Ai::Messaging::Adapters::Webhook — plugs into the existing messaging-adapter framework so it's selected automatically by Ai::Messaging::CallbackWorker at the workflow's created → running / running → finished transitions, and on workload failure. Builds the flow.started / flow.completed / flow.failed payloads and enqueues delivery.
  • Ai::Messaging::WebhookDeliveryWorker — delivers via the existing WebHookService. Unlike WebHookWorker, it raises on a failed delivery so Sidekiq retries it with backoff — rate limiting and auto-disabling a persistently failing hook are intentionally out of scope for now (tracked separately, see gitlab-org/gitlab#607031), so retry-with-backoff is the only per-hook mitigation today.
  • callback_hook_id param on POST /ai/duo_workflows/workflows — resolves the hook scoped to the current organization and persists { adapter: 'webhook', hook_id: } into the workflow's messaging_callback_context before StartWorkflowService runs.
  • Deterministic event_id (Gitlab::UUID.v5) per (workflow, event, hook) so a retried delivery of the same event keeps the same id, letting clients dedupe.
  • Ai::Messaging::AdapterRegistry updated to resolve 'webhook' to the new adapter.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #607028

Merge request reports

Loading
Loading