feat: split card around clarify tool interactions - #99
Merged
Conversation
- inject CLARIFY hook (16th) wrapping agent.clarify_callback - pause card flush while clarify prompt is shown (CLARIFY_PAUSED) - seal old card and create new card after clarify completes - keep session pointing at an unsealed card on timeout cancel - pass explicit card_id/sequence to seal the pre-switch card - add controller tests covering clarify split lifecycle
Cheerwhy
force-pushed
the
feat/clarify-card-split
branch
from
August 5, 2026 05:39
30b1eb2 to
e1ecf92
Compare
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.
Problem
When the model calls Hermes's
clarifytool, a poll is rendered inside the chatwhile the agent worker thread blocks on the user response. The streaming card
keeps accumulating the pre-clarify prose, and once the user answers, the
remaining output is appended to the same card. There is no visual separation
between the prompt and the continuation, and the card grows unboundedly.
Solution
Inject a CLARIFY hook (the 16th) around
agent.clarify_callbackand add aCLARIFY_PAUSEDsession state that freezes card flushes while the clarify pollis visible. When the tool completes, seal the old card and create a fresh
streaming card that carries all post-clarify output.
Card switching is also made cancellation-safe: the session is switched to the
new card before the old one is sealed, so a timeout cancel can never leave the
session pointing at a closed card. Sealing passes the old card's ID and
monotonic sequence explicitly, since CardKit rejects out-of-order updates.
Changes
CLARIFYto the injectable hook list and wrapagent.clarify_callbackin
_run_agent(enter/exit notifications to the controller).SessionState.CLARIFY_PAUSED; pause_schedule_flushwhile a clarifyprompt is showing and resume on tool completion.
_do_clarify_split: flush pending content, create the new card,switch the session, then seal the old card (create → switch → seal order).
card_idandsequencecaptured before theswitch, using a local counter so the new card restarts at sequence 1.
split_disabledin afinallyblock covering cancel/exception paths.fallback, seal-failure behavior, and enter/exit pause semantics.
Compatibility
CLARIFY injection targets
agent.clarify_callback = _clarify_callback_sync(verified at Hermes 0.20.0 line 5098); the anchor is unchanged since 0.14.0,
the declared minimum.
Testing
errors, new card streamed normally