Commit Graph

8 Commits

Author SHA1 Message Date
Ramin Shirali Hossein Zade
1af0edf7ff fix: ensure exec approval is registered before returning (#2402) (#3357)
* feat(gateway): add register and awaitDecision methods to ExecApprovalManager

Separates registration (synchronous) from waiting (async) to allow callers
to confirm registration before the decision is made. Adds grace period for
resolved entries to prevent race conditions.

* feat(gateway): add two-phase response and waitDecision handler for exec approvals

Send immediate 'accepted' response after registration so callers can confirm
the approval ID is valid. Add exec.approval.waitDecision endpoint to wait for
decision on already-registered approvals.

* fix(exec): await approval registration before returning approval-pending

Ensures the approval ID is registered in the gateway before the tool returns.
Uses exec.approval.request with expectFinal:false for registration, then
fire-and-forget exec.approval.waitDecision for the decision phase.

Fixes #2402

* test(gateway): update exec-approval test for two-phase response

Add assertion for immediate 'accepted' response before final decision.

* test(exec): update approval-id test mocks for new two-phase flow

Mock both exec.approval.request (registration) and exec.approval.waitDecision
(decision) calls to match the new internal implementation.

* fix(lint): add cause to errors, use generics instead of type assertions

* fix(exec-approval): guard register() against duplicate IDs

* fix: remove unused timeoutMs param, guard register() against duplicates

* fix(exec-approval): throw on duplicate ID, capture entry in closure

* fix: return error on timeout, remove stale test mock branch

* fix: wrap register() in try/catch, make timeout handling consistent

* fix: update snapshot on timeout, make two-phase response opt-in

* fix: extend grace period to 15s, return 'expired' status

* fix: prevent double-resolve after timeout

* fix: make register() idempotent, capture snapshot before await

* fix(gateway): complete two-phase exec approval wiring

* fix: finalize exec approval race fix (openclaw#3357) thanks @ramin-shirali

* fix(protocol): regenerate exec approval request models (openclaw#3357) thanks @ramin-shirali

* fix(test): remove unused callCount in discord threading test

---------

Co-authored-by: rshirali <rshirali@rshirali-haga.local>
Co-authored-by: rshirali <rshirali@rshirali-haga-1.home>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-13 19:57:02 +01:00
cpojer
f06dd8df06 chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
cpojer
5ceff756e1 chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
Paul van Oorschot
7d0a0ae3ba fix(discord): autoThread ack reactions + exec approval null handling (#1511)
* fix(discord): gate autoThread by thread owner

* fix(discord): ack bot-owned autoThreads

* fix(discord): ack mentions in open channels

- Ack reactions in bot-owned autoThreads
- Ack reactions in open channels (no mention required)
- DRY: Pass pre-computed isAutoThreadOwnedByBot to avoid redundant checks
- Consolidate ack logic with explanatory comment

* fix: allow null values in exec.approval.request schema

The ExecApprovalRequestParamsSchema was rejecting null values for optional
fields like resolvedPath, but the calling code in bash-tools.exec.ts passes
null. This caused intermittent 'invalid exec.approval.request params'
validation errors.

Fix: Accept Type.Union([Type.String(), Type.Null()]) for all optional string
fields in the schema. Update test to reflect new behavior.

* fix: align discord ack reactions with mention gating (#1511) (thanks @pvoo)

---------

Co-authored-by: Wimmie <wimmie@tameson.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-01-23 20:01:15 +00:00
Peter Steinberger
b573231cd1 fix: prevent exec approval resolve race 2026-01-22 07:01:27 +00:00
Lucas Czekaj
de898c423b fix(exec): pass undefined instead of null for optional approval params
TypeBox Type.Optional(Type.String()) accepts string|undefined but NOT null.
Discord exec was failing with 'resolvedPath must be string' because callers
passed null explicitly. Web UI worked because it skipped the approval request.

Fixes exec approval validation error in Discord-triggered sessions.
2026-01-21 18:14:51 -08:00
Peter Steinberger
7e1a17e5e6 fix: unify exec approval ids 2026-01-22 00:59:29 +00:00
Peter Steinberger
dcb8d16591 fix: validate ws tls fingerprint 2026-01-20 13:04:20 +00:00