Skip to content

fix(code): keep rapid typing visible - #5424

Merged
Mason Daugherty (mdrxy) merged 21 commits into
mainfrom
mdrxy/code/keep-rapid-typing-visible
Aug 18, 2026
Merged

fix(code): keep rapid typing visible#5424
Mason Daugherty (mdrxy) merged 21 commits into
mainfrom
mdrxy/code/keep-rapid-typing-visible

Conversation

@mdrxy

Copy link
Copy Markdown
Member

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

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>
@github-actions github-actions Bot added dcode Related to `deepagents-code` fix A bug fix (PATCH) internal User is a member of the `langchain-ai` GitHub organization size: S 50-199 LOC labels Aug 11, 2026
@mdrxy
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.
@github-actions github-actions Bot added size: L 500-999 LOC and removed size: S 50-199 LOC labels Aug 11, 2026
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.
@github-actions github-actions Bot added size: XL 1000+ LOC and removed size: L 500-999 LOC labels Aug 17, 2026
…-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.
@mdrxy
Mason Daugherty (mdrxy) merged commit 6a7c7d6 into main Aug 18, 2026
55 of 56 checks passed
@mdrxy
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dcode Related to `deepagents-code` fix A bug fix (PATCH) internal User is a member of the `langchain-ai` GitHub organization size: XL 1000+ LOC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant