hermes - ✅(Solved) Fix [Feature]: TUI Autocompletion: Tab Key Does Not Accept Completions [1 pull requests, 1 comments, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#15622Fetched 2026-04-26 05:26:05
View on GitHub
Comments
1
Participants
1
Timeline
5
Reactions
0
Participants
Timeline (top)
labeled ×3commented ×1cross-referenced ×1

Fix Action

Fixed

PR fix notes

PR #15623: fix(tui): restore autocompletion Tab acceptance in TextInput

Description (problem / solution / changelog)

What does this PR do?

Restores interactive message autocompletion in the Hermes TUI by fixing Tab key acceptance. The TUI displayed a completion dropdown (slash commands, file paths) but pressing Tab did nothing — users could not accept suggestions with the keyboard. The root cause was that TextInput never received completion props and had no key handler to apply them.

This matches the behavior of the old prompt_toolkit-based CLI, where Tab accepts the highlighted completion and positions the cursor accordingly.

Related Issue

Fixes the interactive message autocompletion regression.

Fixes #15622

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

FileChange
ui-tui/src/components/textInput.tsxExtended TextInputProps with completions, compIdx, compReplace, setCompIdx; implemented Tab/Shift+Tab key handler to accept/cycle completions; removed Tab from early-return block
ui-tui/src/components/appLayout.tsxPassed completion props (completions, compIdx, compReplace, setCompIdx) from composer state to TextInput
ui-tui/src/app/interfaces.tsAdded compReplace: number to AppLayoutComposerProps; corrected setCompIdx type to StateSetter<number>
ui-tui/src/app/useMainApp.tsIncluded compReplace in appComposer object; typed useMemo with AppLayoutComposerProps for type safety

How to Test

  1. Build the TUI: cd ui-tui && npm run build
  2. Launch Hermes in TUI mode: hermes --tui
  3. Type / in the message composer — a dropdown of slash commands appears
  4. Press Tab — the highlighted command inserts at the cursor, cursor moves after inserted text
  5. Press Tab again — cycles to the next completion, replacing the previous one
  6. Press Shift+Tab — cycles backward through the completions list
  7. Press Enter or type any letter — overlay dismisses, key types normally
  8. Repeat with @ to test file path completion (same behavior)

Expected: Tab accepts and inserts; Shift+Tab cycles backward; other keys dismiss overlay.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(tui): restore autocompletion Tab acceptance in TextInput)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass (TUI unit tests not executed locally; build and type-check on modified files pass)
  • I've added tests for my changes (recommended: src/__tests__/textInputAutocomplete.test.tsx covering Tab/Shift+Tab/Enter dismissal/cursor placement)
  • I've tested on my platform: Ubuntu 24.04

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) — Tab/Shift+Tab handling is platform-agnostic; matches prompt_toolkit behavior
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

For New Skills

Not applicable — this is a core TUI bug fix, not a skill.

Screenshots / Logs

N/A (text-based UI behavioral fix verified manually)

Build output:

ui-tui/src/components/textInput.tsx    39 ++++++++++++++++++++++++++++
ui-tui/src/components/appLayout.tsx     4 +++
ui-tui/src/app/interfaces.ts            2 ++
ui-tui/src/app/useMainApp.ts           35 ++++++++++++++-------------
4 files changed, 59 insertions(+), 21 deletions(-)

TypeScript: zero errors on modified files
Bundle: dist/ink-bundle.js generated (400 KB)

Changed files

  • ui-tui/src/app/interfaces.ts (modified, +2/-0)
  • ui-tui/src/app/useMainApp.ts (modified, +17/-18)
  • ui-tui/src/components/appLayout.tsx (modified, +4/-0)
  • ui-tui/src/components/textInput.tsx (modified, +36/-3)
RAW_BUFFERClick to expand / collapse

Problem or Use Case

The Hermes TUI (terminal UI) displays a dropdown for message autocompletion — slash commands (e.g., /help, /model) when typing /, and file paths when typing @. However, pressing Tab does nothing; the highlighted suggestion is never inserted. This is a regression from the original prompt_toolkit-based CLI, where Tab accepted completions automatically.

Impact:

  • Users cannot use keyboard-driven completion — they must type full commands manually
  • The dropdown is purely decorative, providing visual feedback without functional acceptance
  • Breaks expected terminal UI conventions (Tab cycles/accepts, Shift+Tab goes backward)

Proposed Solution

Wire the completion state from useCompletion through to the TextInput component and implement Tab/Shift+Tab key handling:

  1. Pass completion props (completions, compIdx, compReplace, setCompIdx) from AppLayoutTextInput
  2. Extend TextInputProps interface to include these fields
  3. Intercept Tab and Shift+Tab in TextInput's key handler:
    • Tab: accepts the current completion, inserts text at the compReplace range, positions cursor after inserted text
    • Shift+Tab: cycles backward through the completions list via setCompIdx
  4. Ensure proper typing in interfaces.ts (setCompIdx as StateSetter<number>) and include compReplace in AppLayoutComposerProps and useMainApp state construction

This approach is minimal and localized — no changes to useCompletion, gateway RPCs, or overlay rendering. It restores the old CLI's acceptance behavior in the new TUI.

Alternatives Considered

  • Handle acceptance in parent (AppLayout): Would require lifting edit state upward and breaking the encapsulated TextInput edit model. Rejected — TextInput already owns the text state and cursor; acceptance belongs there.
  • Global key capture at app.tsx level: Adds indirection and complicates prop drilling. Rejected — TextInput already receives key events; keeping logic local is cleaner.
  • Disable Tab for completions and use Enter: Misaligns with terminal UX norms (Tab is standard for completion acceptance in prompt_toolkit, readline, etc.). Rejected — would create inconsistency.
  • Re-implement entire completion system: Unnecessary — the dropdown renders correctly and completion data is already flowing to appOverlays. Only acceptance logic was missing.

Feature Type

Other

Scope

Small (single file, < 50 lines)

Contribution

  • I'd like to implement this myself and submit a PR

Debug Report (optional)

extent analysis

TL;DR

Implement Tab and Shift+Tab key handling in the TextInput component to accept and cycle through completions.

Guidance

  • Pass completion props from AppLayout to TextInput and extend the TextInputProps interface to include these fields.
  • Intercept Tab and Shift+Tab keys in TextInput's key handler to accept the current completion and cycle backward through the completions list.
  • Ensure proper typing in interfaces.ts for setCompIdx and include compReplace in AppLayoutComposerProps and useMainApp state construction.
  • Verify that the completion dropdown is functional and that Tab and Shift+Tab keys work as expected.

Example

// In TextInput's key handler
if (key === 'Tab') {
  // Accept the current completion and insert text at the compReplace range
  const completion = completions[compIdx];
  const newText = completion.text;
  // Insert text and position cursor after inserted text
} else if (key === 'Shift+Tab') {
  // Cycle backward through the completions list
  setCompIdx((prevIdx) => (prevIdx - 1 + completions.length) % completions.length);
}

Notes

This solution assumes that the completion data is already flowing to appOverlays and that the dropdown renders correctly. The focus is on implementing the acceptance logic for Tab and Shift+Tab keys.

Recommendation

Apply the proposed solution to implement Tab and Shift+Tab key handling in the TextInput component, as it restores the expected terminal UI conventions and provides a functional completion dropdown.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix [Feature]: TUI Autocompletion: Tab Key Does Not Accept Completions [1 pull requests, 1 comments, 1 participants]