Skip to content

fix(ui): prevent duplicate user prompt rendering in inline mode - #1182

Open
Rudra2637 wants to merge 2 commits into
Nano-Collective:mainfrom
Rudra2637:fix/duplicate-inline-prompt
Open

fix(ui): prevent duplicate user prompt rendering in inline mode#1182
Rudra2637 wants to merge 2 commits into
Nano-Collective:mainfrom
Rudra2637:fix/duplicate-inline-prompt

Conversation

@Rudra2637

Copy link
Copy Markdown

Description

Fixes an issue in default inline mode (non-alt-screen) where submitted user prompts are duplicated in the terminal scrollback history when the model begins streaming its response.

Issue link: #1174

Root Cause

In default inline mode, chat transcript history is backed by Ink's <Static> component. When a prompt was submitted, renderLastQueuedComponentLive placed the message in the live dynamic region (to support draft recall before streaming starts). Once the model began streaming and the recall window closed, moving the message into <Static items={allStaticComponents}> caused Ink to reprint the component directly into terminal stdout, duplicating the prompt.

Fix

  • Gated renderLastQueuedComponentLive to only activate in fullscreen (--alt-screen) mode where <Static> is disabled and rendering occurs inside a virtual scrolling viewport.
  • In inline mode, submitted prompts are immediately kept in the static queue, preventing redundant stdout reprints when streaming begins.
  • Added unit test in source/app/components/chat-history.spec.tsx verifying inline mode behavior.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Changeset

  • Added a changeset (pnpm changeset) describing this change for the changelog

Testing

Automated Tests

  • New features include passing tests in .spec.ts/tsx files
  • All existing tests pass (pnpm test:ava source/app/components/chat-history.spec.tsx source/components/chat-queue.spec.tsx - 32/32 tests passed)
  • TypeScript checks pass (tsc --noEmit)
  • Biome formatting/linter checks pass (biome check .)

Manual Testing

  • Tested with Ollama in default inline mode (verified prompt appears exactly once)
  • Tested in fullscreen mode (--alt-screen) to ensure no regression in alt-screen rendering

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • No breaking changes (or clearly documented)

Copilot AI lite review requested due to automatic review settings September 4, 2026 11:05
@github-actions github-actions Bot added the area:tui Terminal UI label Sep 4, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The newly added unit test doesn’t currently exercise the live→Static transition that caused the duplication, so it would pass even if the regression reappeared.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Fixes duplicate user-prompt rendering in default inline (non-alt-screen) mode by preventing the “last queued component rendered live” behavior from being used when Ink’s <Static> transcript is active (which otherwise reprints content into stdout during the live→static transition).

Changes:

  • Gate renderLastQueuedComponentLive to fullscreen/alt-screen mode in InteractiveApp.
  • Add a defensive gate inside ChatHistory so inline mode never enables live queue rendering.
  • Add a unit test and a changeset entry for the patch release note.
File summaries
File Description
source/app/sections/interactive-app.tsx Only enables last-queued live rendering when fullscreen is active.
source/app/components/chat-history.tsx Forces inline mode to keep queued components in the Static-backed transcript to avoid duplicate stdout prints.
source/app/components/chat-history.spec.tsx Adds a test intended to cover inline-mode behavior (needs improvement to actually detect duplication).
.changeset/fix-duplicate-inline-prompt.md Documents the bugfix for the changelog as a patch changeset.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +209 to +223
test('inline mode keeps queued components in static queue even if renderLastQueuedComponentLive is passed', t => {
const props = createDefaultProps({
fullscreen: false,
queuedComponents: [
<div key="msg1">Message 1</div>,
<div key="msg2">Message 2</div>,
],
renderLastQueuedComponentLive: true,
});
const {lastFrame, unmount} = renderWithTheme(<ChatHistory {...props} />);
const output = lastFrame() ?? '';
t.regex(output, /Message 1/);
t.regex(output, /Message 2/);
unmount();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:tui Terminal UI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants