Skip to content

[Bugfix] Fix completion approval problem#63

Open
droidlyx wants to merge 2 commits intoResearAI:mainfrom
droidlyx:fix_completion_approval_ux
Open

[Bugfix] Fix completion approval problem#63
droidlyx wants to merge 2 commits intoResearAI:mainfrom
droidlyx:fix_completion_approval_ux

Conversation

@droidlyx
Copy link
Copy Markdown

@droidlyx droidlyx commented Apr 28, 2026

Summary

Closes a UX bug exposed by quest 014: ending an autonomous quest required
the user to send "同意" four times before complete_quest fired. The issue is fixed in two
self-contained commits:

  • Commit 1 — UI default reply target. findReplyTargetId walked the
    feed once and returned at the first artifact whose replyMode was
    'blocking' or 'threaded'. The mailbox-poll __noop__ heartbeats
    always sat after the actual quest_completion_approval decision, so
    the threaded fallback fired first and the blocking decision was never
    reached. Split into two passes: prefer any unresolved blocking /
    expectsReply artifact; only fall back to the latest threaded one
    when none exists. Function is now exported and unit-tested.

  • Commit 2 — Suppress noop heartbeats while a blocking interaction is
    pending.
    Added _has_unresolved_blocking_interaction(quest_root)
    (any open_requests entry with status='waiting' is by construction
    blocking, since _update_interaction_state only inserts on
    reply_mode='blocking'). In interact(), short-circuit before the
    existing dedupe block: when the call is a __noop__ /
    __mailbox_poll__ progress heartbeat and a blocking interaction is
    still waiting, return status='suppressed_blocking_pending' without
    recording an artifact. Substantive progress messages still record
    normally — only mailbox-poll noops are suppressed.

Together: the UI no longer mis-routes "同意" onto a heartbeat, and the
runtime stops emitting heartbeats that would push the actual approval
request further down the user's feed in the first place.

AI Assistance

This PR was prepared with AI assistance and reviewed locally before submission.

droidlyx and others added 2 commits April 28, 2026 12:30
…for default reply target

Quest 014's user had to send "同意" four times before complete_quest fired:
the React workspace's default `reply_to_interaction_id` always resolved to
the most recent threaded `progress` heartbeat (e.g. mailbox-poll `__noop__`)
even when an unresolved `quest_completion_approval` decision was waiting
behind it in the feed.

`findReplyTargetId` previously walked the feed once and returned at the
first artifact with either `replyMode === 'blocking'` or `replyMode ===
'threaded' && interactionId`. Because that single loop returned on the
threaded fallback as soon as it saw a recent heartbeat, the older blocking
decision was never reached.

Split into two passes: first scan for a blocking / `expectsReply`
artifact; only when none exists fall back to the latest threaded
interaction. Export the function so it can be unit tested.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…action is unresolved

While quest 014 waited for a user reply on its quest_completion_approval
decision_request, the runtime emitted ~12 `__noop__` mailbox-poll progress
heartbeats over four hours. Each one was committed to git, recorded in the
interaction journal, and queued for connector delivery — and each one
pushed the actual approval request further down the user's feed, making
"同意" land on a heartbeat instead of the decision.

Add `_has_unresolved_blocking_interaction(quest_root)` which scans
`open_requests` for any waiting entry — by construction these are always
blocking, since `_update_interaction_state` only inserts into
`open_requests` for `reply_mode='blocking'` calls.

In `interact()`, short-circuit before the existing dedupe block: when the
incoming call is a `__noop__` / `__mailbox_poll__` progress heartbeat and
a blocking interaction is still waiting on the user, return
`status='suppressed_blocking_pending'` without recording an artifact. The
substantive-progress path is unchanged, so a real status update (e.g.
"training crashed at step 1200") still records normally even during a
blocking wait.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@droidlyx droidlyx changed the title Fix completion approval ux [Bugfix] Fix completion approval problem Apr 28, 2026
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