fix(workflows): cron approval buttons + Telegram text-reply fallback#457
Merged
Conversation
…QL connection Cron-triggered workflow runs close their throwaway postgres connection (cron/service/timer.ts) the instant executeWorkflowRunFromRow returns. The approval notification dispatched fire-and-forget from onApprovalRequested (notifyWorkflowApprovalRequest + markWorkflowApprovalNotified) was therefore abandoned mid-flight, so the operator never received the inline-button approval message and workflow_approvals.notification_status stayed 'pending'. Manual / dashboard / webhook paths use the long-lived shared pool and were unaffected. Track the notification promises and drain them (bounded by a 20s cap) before returning, keeping opts.sql alive until markWorkflowApprovalNotified runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ny fallback) Adds a no-buttons fallback: in the chat that receives approval notifications (operatorNotifications telegram targets), replying 'approve'/'deny' (optionally 'approve <run-id-prefix>') resolves the pending approval and resumes the run — the same path the inline button callback uses. Single pending → resolves it; multiple → lists them and asks which; zero → friendly no-op; bad token → not-found. Scoped to operator notification chats and requires the message be exactly the keyword (+optional id) so it never hijacks normal conversation. selectApprovalForTextCommand holds the pure branching (unit-tested); listPendingWorkflowApprovals backs the discovery query. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
This was referenced Jun 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the operator-facing workflow-approval breakage surfaced 2026-06-16: cron-triggered approvals arrived as plain, button-less Telegram messages and "approve" replies did nothing. Two code fixes + one config reconcile (the third is operator-side, applied separately).
Bug #1 — cron approvals never sent inline buttons
onApprovalRequesteddispatches the approval notification (notifyWorkflowApprovalRequest+markWorkflowApprovalNotified) fire-and-forget. The cron runner (cron/service/timer.ts) closes its throwaway postgres connection the instantexecuteWorkflowRunFromRowreturns, abandoning that work mid-flight — so the inline-button message never sent andworkflow_approvals.notification_statusstuck atpending. Manual/dashboard/webhook paths use the long-lived shared pool and were unaffected (DB confirmed:manual=sent,cron=pending).Fix: track the notification promises and drain them (bounded by 20s) before returning, keeping the connection alive until
markWorkflowApprovalNotifiedruns.Bug #2 — no text-reply fallback
Approvals resolved only via the
wf_app:button callback or dashboard. Added a Telegram text handler: in the operator's notification chat, replyingapprove/deny(optionallyapprove <run-id-prefix>) resolves the pending approval and resumes the run. Single pending → resolves; multiple → lists choices; zero → no-op; bad token → not-found. Scoped to operator-notification chats; requires the message be exactly the keyword (+optional id) so it never hijacks normal conversation. Pure branching extracted toselectApprovalForTextCommand(unit-tested).Tests
workflow-execution-service.approval-drain.test.ts— notify+markNotified complete before the run connection closes, even with a slow notify.workflow-approvals.text-command.test.ts— selector covers single/multi/zero/token cases.Not in this PR
DASHBOARD_API_TOKENin~/.argentos/.envshadowed the canonicalgateway.auth.token; removed so both gateway and api-server use the canonical token. Operator/live action, applied separately.🤖 Generated with Claude Code