Skip to content

feat(webhook): support all HITL template response formats#213

Merged
AbirAbbas merged 2 commits intomainfrom
feat/webhook-approval-multi-template
Mar 4, 2026
Merged

feat(webhook): support all HITL template response formats#213
AbirAbbas merged 2 commits intomainfrom
feat/webhook-approval-multi-template

Conversation

@AbirAbbas
Copy link
Contributor

Summary

  • Multi-template support: Extract decision from both decision and action response fields, covering all 14 HITL template types (text-approval, confirm-action, signature-capture, rich-text-editor, etc.)
  • Decision normalization: New normalizeDecision() maps template-specific values (approve, confirm, reject, deny, abort, cancel) to the canonical set (approved/rejected/request_changes/expired)
  • Multi-pause workflows: Clear approval request fields on approved (not just request_changes) so agents can issue sequential approval requests within the same execution
  • Default completed→approved: Templates that submit without an explicit decision/action field (e.g. signature-capture) now default to approved when the webhook type is completed
  • CORS: Add localhost:8001 for demo UIs

Context

Previously only templates using the decision field in their response worked with the webhook approval handler. Templates using action (confirm-action, rich-text-editor) or no explicit field (signature-capture) would fail to extract a decision, causing 400 errors. This blocked the finance-compliance and supply-chain demos from completing HITL workflows with certain template types.

Test plan

  • Verify text-approval template (uses decision) still works
  • Verify confirm-action template (uses action) now resolves correctly
  • Verify signature-capture template (no decision field, completed type) defaults to approved
  • Test multi-pause workflow: first approval resolves, agent issues second approval request
  • Verify request_changes still clears approval fields as before

🤖 Generated with Claude Code

…ause workflows

The webhook approval handler previously only extracted the "decision" field
from template responses, causing templates that use "action" (confirm-action,
rich-text-editor) or have no explicit decision field (signature-capture) to
fail silently.

Changes:
- Extract decision from "action" field as fallback when "decision" is absent
- Default completed webhooks with no decision/action to "approved"
- Add normalizeDecision() to map template-specific values (approve, confirm,
  reject, deny, abort, cancel) to canonical set (approved/rejected)
- Clear approval request fields on "approved" (not just "request_changes")
  to support multi-pause workflows where agents issue sequential approvals
- Add localhost:8001 to CORS allowed origins for demo UIs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AbirAbbas AbirAbbas requested a review from a team as a code owner March 3, 2026 22:40
…-pause

The previous commit cleared ApprovalRequestID on both "approved" and
"request_changes" decisions. This broke:
- Idempotent webhook retries (lookup by request ID returned 404)
- Approval-status queries (same lookup failure)
- Callback notifications (in-memory store shared pointer was mutated)

Fix:
- Only clear ApprovalRequestID on "request_changes" (as before)
- On "approved", clear URL fields but preserve the request ID
- Save callback URL before the update closure to avoid shared-pointer
  aliasing in stores that mutate objects in-place
- Make request-approval handler multi-pause aware: check ApprovalStatus
  is "pending" (not just ApprovalRequestID existence) so agents can
  re-request approval after a resolved round

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AbirAbbas AbirAbbas merged commit aa15d64 into main Mar 4, 2026
17 checks passed
@AbirAbbas AbirAbbas deleted the feat/webhook-approval-multi-template branch March 4, 2026 02:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant