fix(code): keep rapid typing visible - #5424
Merged
Mason Daugherty (mdrxy) merged 21 commits intoAug 18, 2026
Merged
Conversation
Delay paste-buffer promotion until a rapid embedded newline confirms a key-event paste, preserving multiline grouping without hiding ordinary keystrokes. Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Mason Daugherty (mdrxy)
marked this pull request as ready for review
August 11, 2026 21:52
A terminal without bracketed paste replays a dropped media file as rapid key events. The previous fix for fast typing delayed burst promotion until a newline arrived, which meant single-line unquoted drops were never promoted into the burst buffer and therefore never rejected by _reject_dropped_media. Add _check_burst_run_for_dropped_media to the shared paste-burst state machine. After each printable key is inserted, if the detected run reaches burst threshold and matches the dropped-path shape (/, ~, drive letter, file://, UNC), promote it immediately and flush so the subclass rejection hook runs. Ordinary fast typing is unaffected because it never starts with those characters. Add regression tests for both the unquoted media burst rejection and for rapid typing staying visible.
A rapid keystroke run now stays in the document until something confirms it is a paste: an embedded newline, a dropped-path shape, or a length no human reaches at burst speed. Only then is the run promoted into the hidden burst buffer, so ordinary fast typing is never pulled off screen. Also fixes the space-key early return bypassing burst tracking, which desynchronised the run tracker from the document and failed every later promotion in that paste.
Rapid-key paste detection guesses whether a fast keystroke run is a paste.
Two helpers supporting that guess had defects that corrupted or swallowed
input.
The command-mode path recovery asked `looks_like_dropped_payload` about a
candidate it had just prefixed with `/`. That function is a leading-token
check, so the question was vacuously true and every rapid run in command
mode qualified: the run was hidden, the input silently left command mode,
and the flush re-inserted a `/` the user never typed. Recovery now requires
the run to start at document offset 0, to contain its own separator, and to
have no whitespace before it, so `help` stays a command name and
`read src/main.py` keeps its command semantics. `_check_burst_run_for_promotion`
gains the slash-command guard its sibling already had, with a documented
exception for a recovered path.
A recovered path that does not resolve on disk falls through to a plain
insert at offset 0, which tripped mode-prefix detection a second time and
stripped the restored slash again. The insert now suppresses that detection
for exactly that payload.
The deferred-space gate held every keystroke behind a posted payload but
was cleared in a single place, so a dropped message, an unmounted owner, or
a raising handler left the input permanently dead. It also rebuilt held
keys as synthetic events, which never reach binding resolution or bubble to
`ChatInput`, losing `tab`, arrow keys, and `alt+backspace`. The gate now
arms only when dispatch actually posted a message, lets non-printable keys
resolve it and take their normal path, drains destructively from the front
inside `try/finally`, and carries a watchdog plus a reset hook so it cannot
stick.
Also: reset the run when the completion branch swallows a printable space;
log burst-run divergence, abandoned promotion, and the unreachable
live-buffer Enter case at warning; refuse promotion instead of substituting
a bogus monotonic timestamp; drop the held space when a path replacement
already appended one; restore exactly one leading slash instead of
`lstrip("/")`; and correct comments that overstated the guarantees.
…-typing-visible # Conflicts: # libs/code/deepagents_code/tui/widgets/chat_input.py
A flushed paste burst was applied by posting `PastedPaths`/`PastedText` to the owner, so the payload landed on a later event-loop turn. Textual appends a posted message to the tail of the widget's FIFO queue, behind any key the terminal already delivered, so the next keystroke was inserted ahead of the paste: typing `y` as a burst broke produced `y[Pasted text #1]`. A paste split across a slow terminal read boundary came out scrambled. Route every payload through `ChatInput.apply_paste_payload` instead, called synchronously from the burst flush, the bracketed-paste handler, and `handle_external_paste` (which already applied its payloads this way). The payload is in the document before the flush returns, so handling the current key afterwards orders it after the paste. The deferred-space gate existed to work around the posted application for one key, holding keystrokes and replaying them as synthetic events. Synchronous dispatch makes it unnecessary, so drop it along with the `DeferredSpace` message, its watchdog, and the six fields it tracked. A replayed key never bubbled to `ChatInput` and never reached binding resolution, so removing the gate also stops `tab`, `enter`, and `ctrl+c` being swallowed behind a held space. Also clear `_burst_payload_keeps_leading_slash` when the buffer it describes is discarded; a stale flag spent one mode re-detection on a later burst.
The double-space guard after a burst flush asked whether the document happened to end in a space, not whether the flush had appended one. A payload inserted verbatim that ended in a space therefore swallowed the user's next spacebar press — one space of a pasted indent, silently. `_insert_pasted_paths` now reports whether `_build_path_replacement` supplied the trailing space, and the guard reads that fact. `_flush_paste_burst` also cleared the buffer before dispatching, while promotion had already deleted the run from the document. A raising dispatch — media decode, attachment tracking, or a notification during teardown — left the text nowhere at all. The payload is now re-inserted verbatim before the error propagates. Three tests named for the rapid-typing regression asserted only after a pause long enough for the flush timer to restore the text, so they passed with the bug reintroduced. They now assert while typing.
Mason Daugherty (mdrxy)
deleted the
mdrxy/code/keep-rapid-typing-visible
branch
August 18, 2026 18:36
Mason Daugherty (mdrxy)
pushed a commit
that referenced
this pull request
Aug 19, 2026
> [!CAUTION] > Merging this PR will automatically publish to **PyPI** and create a **GitHub release**. For the full release process, see [`.github/RELEASING.md`](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md). --- _Release notes preview: keep this section in sync with the package `CHANGELOG.md`. Publish reads the merged CHANGELOG via `release.yml`, not this PR description — keep them aligned anyway so the PR stays an accurate historical record for reviewers and anyone returning later._ --- ## [0.1.58](deepagents-code==0.1.57...deepagents-code==0.1.58) (2026-08-19) ### Breaking Changes - `deepagents-code` now requires Python 3.12 or newer. ([#5603](#5603)) ### Features - Added OpenRouter `z-ai/glm-5.3` to the model switcher. ([#5641](#5641)) - Added support for re-authenticating MCP servers from the viewer. ([#5637](#5637)) - Footer pickers can now be opened with `ctrl+click`. ([#5611](#5611)) - Resume hints now account for `TERM_PROGRAM` support before showing terminal-specific guidance. ([#5580](#5580)) ### Fixes - Completed the `dcode config` command surface. ([#5581](#5581)) - Made `/offload` interruptible. ([#5590](#5590)) - Improved chat and footer UI behavior: rapid typing stays visible, double-click collapses a resized chat input, and the MCP footer wraps on narrow windows. ([#5424](#5424), [#5578](#5578), [#5651](#5651)) - Captured stdio MCP server stderr in the logger. ([#5610](#5610)) - Drained hook pipes after timeout. ([#5606](#5606)) - Grouped resume trace rounds. ([#5593](#5593)) - Omitted web-search prompt guidance when web search is unavailable. ([#5602](#5602)) - Resolved message pointer shapes per cell. ([#5592](#5592)) _End release notes preview._ --- > [!NOTE] > A **community contributors** list and a **Special thanks** section (crediting the users who filed the issues this release's PRs closed) are appended to the GitHub release notes automatically at publish time (see [Release Pipeline](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md#release-pipeline), step 3). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: langchain-oss-automated-triage[bot] <248757908+langchain-oss-automated-triage[bot]@users.noreply.github.com>
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.
Rapid typing in the chat input and inline prompts now stays visible instead of disappearing until typing pauses.
Rapid printable runs previously moved into the hidden paste buffer after three keys. Promotion now waits for an embedded newline to confirm a key-event paste, preserving multiline grouping and collapse behavior without delaying ordinary typing.
Made by Open SWE
References