Skip to content

.NET: Fix render dupe and text input clear bugs, and improve guardrail error messaging#6136

Merged
westey-m merged 9 commits into
microsoft:mainfrom
westey-m:harness-console-rendering-dupe-bugs
May 28, 2026
Merged

.NET: Fix render dupe and text input clear bugs, and improve guardrail error messaging#6136
westey-m merged 9 commits into
microsoft:mainfrom
westey-m:harness-console-rendering-dupe-bugs

Conversation

@westey-m
Copy link
Copy Markdown
Contributor

@westey-m westey-m commented May 28, 2026

Motivation and Context

  • The input text box was not always rendered fully after switching from list selection back to input box views
  • Re-rendering of the last item in the scroll view did not take into account line wrapping

Description

  • Fix bug where line wrapping caused duplicate text to render.
  • Fix bug where approve and continue text or spinner/usage was shown in text input box.
  • Improve guardrail error text since just printing the error code was not clear enough
  • Gracefully fall back to text output when structured output fails

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

Copilot AI review requested due to automatic review settings May 28, 2026 09:48
@moonbox3 moonbox3 added the .NET label May 28, 2026
@github-actions github-actions Bot changed the title Fix render dupe and text input clear bugs .NET: Fix render dupe and text input clear bugs May 28, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the .NET Harness console UI rendering logic to better handle terminal wrapping and bottom-panel mode switches.

Changes:

  • Adds ANSI-aware visible string length measurement.
  • Updates queued/scroll text height calculations to account for wrapping.
  • Forces bottom-panel repaint when switching modes to avoid stale content.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
dotnet/samples/02-agents/Harness/ConsoleReactiveComponents/AnsiEscapes.cs Adds visible-length calculation for ANSI-styled strings.
dotnet/samples/02-agents/Harness/ConsoleReactiveComponents/TextPanel.cs Updates queued panel height/rendering to account for wrapped physical rows.
dotnet/samples/02-agents/Harness/ConsoleReactiveComponents/TextScrollPanel.cs Updates scroll-panel last-item offset calculation for wrapped rows.
dotnet/samples/02-agents/Harness/Harness_Shared_Console/HarnessAppComponent.cs Passes console width into queued-panel measurement and invalidates bottom child on mode changes.
Comments suppressed due to low confidence (1)

dotnet/samples/02-agents/Harness/ConsoleReactiveComponents/TextPanel.cs:58

  • This loop compares the global currentRow against the current item's lineCount, so after rendering a one-line item currentRow is already 1 and subsequent one-line items are skipped entirely. It also advances only one row for a logical line that may wrap. Track rows rendered for the current item separately and advance currentRow by the physical rows occupied by each logical line/item.
            for (int j = 0; j < lines.Length && currentRow < lineCount; j++)
            {
                Console.Write(AnsiEscapes.MoveAndEraseLine(props.Y + currentRow));
                Console.Write(lines[j]);
                currentRow++;

Comment thread dotnet/samples/02-agents/Harness/ConsoleReactiveComponents/TextPanel.cs Outdated
Comment thread dotnet/samples/02-agents/Harness/ConsoleReactiveComponents/TextScrollPanel.cs Outdated
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Automated Code Review

Reviewers: 4 | Confidence: 89% | Result: All clear

Reviewed: Correctness, Security Reliability, Test Coverage, Design Approach


Automated review by westey-m's agents

@westey-m westey-m marked this pull request as draft May 28, 2026 10:04
@westey-m westey-m changed the title .NET: Fix render dupe and text input clear bugs .NET: Fix render dupe and text input clear bugs, and improve guardrail error messaging May 28, 2026
@westey-m westey-m requested a review from Copilot May 28, 2026 10:33
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

dotnet/samples/02-agents/Harness/ConsoleReactiveComponents/TextPanel.cs:58

  • lineCount now includes wrapped terminal rows, but currentRow is still incremented only once per logical line. For a long line that wraps, the leftover-line cleanup starts too early and erases the wrapped continuation rows (and later items can be positioned over them); advance currentRow by the physical row count for each logical line instead.
            int lineCount = CountPhysicalLines(text, props.Width);

            for (int j = 0; j < lines.Length && currentRow < lineCount; j++)
            {
                Console.Write(AnsiEscapes.MoveAndEraseLine(props.Y + currentRow));
                Console.Write(lines[j]);
                currentRow++;

Comment thread dotnet/samples/02-agents/Harness/ConsoleReactiveComponents/TextPanel.cs Outdated
Comment thread dotnet/samples/02-agents/Harness/ConsoleReactiveComponents/TextPanel.cs Outdated
@westey-m westey-m marked this pull request as ready for review May 28, 2026 12:40
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Automated Code Review

Reviewers: 4 | Confidence: 88%

✓ Correctness

The PR correctly addresses the stated bugs: line wrapping is now accounted for in physical line counting (using overflow-safe ceiling division), the bottom panel invalidation on mode change ensures proper repaint, and the shared static render lock prevents ANSI interleaving. The previously raised overflow and duplication concerns are properly resolved. No new correctness issues found.

✓ Security Reliability

The PR is sound from a security/reliability perspective. The shared static render lock uses C#'s rentrant Monitor, so nested acquisitions within RenderCore (e.g., calling child.Invalidate()) are safe on the same thread. The GetContentFilterDetails method properly disposes JsonDocument via 'using' and wraps all parsing in a catch-all since it's non-critical diagnostic output. The PlanningOutputObserver fallback gracefully renders unparseable responses as text rather than failing. The CountPhysicalLines math is overflow-safe with the ceiling-division formula for positive terminal widths.

✓ Test Coverage

This PR modifies console rendering logic in a sample/harness application that has no existing test infrastructure. The new AnsiEscapes.VisibleLength and AnsiEscapes.CountPhysicalLines utility methods are pure functions with well-defined inputs/outputs that are highly testable and now serve as shared logic for correct rendering across multiple components. While this is sample code, these helpers are algorithmic in nature and could benefit from unit tests — especially given the prior review thread identifying edge cases (overflow, zero-width, emoji). The rendering, observer, and framework changes involve Console I/O and are harder to unit test without mocking infrastructure.

✗ Design Approach

The wrapped-height changes are headed in the right direction, but TextPanel still does not repaint wrapped content the same way it measures it. In the new render loop, wrapped logical lines advance currentRow by multiple rows without clearing those continuation rows first, so a rerender where content shrinks can still leave stale text on screen.

Flagged Issues

  • TextPanel.cs:59 only erases the first physical row of a logical line even when linePhysicalRows > 1, so rerendering shorter wrapped content leaves stale continuation rows behind.

Automated review by westey-m's agents

@westey-m westey-m added this pull request to the merge queue May 28, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 28, 2026
@westey-m westey-m added this pull request to the merge queue May 28, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks May 28, 2026
@westey-m westey-m added this pull request to the merge queue May 28, 2026
@westey-m westey-m removed this pull request from the merge queue due to a manual request May 28, 2026
@westey-m westey-m merged commit e6762ea into microsoft:main May 28, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants