Skip to content

fix(tui): avoid duplicated streamed markdown lines#26618

Open
fcoury-oai wants to merge 12 commits into
mainfrom
fcoury/fix-dupe-line
Open

fix(tui): avoid duplicated streamed markdown lines#26618
fcoury-oai wants to merge 12 commits into
mainfrom
fcoury/fix-dupe-line

Conversation

@fcoury-oai

Copy link
Copy Markdown
Contributor

Summary

  • keep a small mutable markdown source tail for streamed assistant messages so CommonMark list continuations are not committed to scrollback before their block boundary is stable
  • keep the structural final reflow path limited to table holdback, instead of treating ordinary mutable tail text as requiring a scrollback rewrite
  • add a regression for the reported bullet-list + fenced-code shape that duplicated an Expected: line in the live TUI

Investigation

The reported session was 019e980f-52de-7851-a519-7204b1fcca61. Its stored rollout contained the duplicated screenshot line only once in the final assistant message, which points at the live incremental TUI renderer rather than model output or history serialization.

The issue reproduced when the stream committed a list-continuation line immediately after a fenced code block. A following blank line/list marker can still change how CommonMark interprets that newest block, so the stale rendered row remained in scrollback and the final render emitted it again.

Testing

  • just test -p codex-tui streaming::controller
  • just test -p codex-tui flush_answer_stream
  • just fmt
  • git diff --check

Notes

just argument-comment-lint was blocked locally by a Bazel/LLVM compiler-rt glob error. The file-scoped wrapper was also blocked by missing dotslash, and the direct source fallback was blocked by the pinned nightly being too old for sqlx 0.9.0. I manually inspected the touched Rust diff for opaque positional literal arguments.

@fcoury-oai fcoury-oai marked this pull request as ready for review June 5, 2026 14:44
@fcoury-oai fcoury-oai force-pushed the fcoury/fix-dupe-line branch from 0c9585b to 31bd9c3 Compare June 5, 2026 15:22
fcoury-oai added a commit that referenced this pull request Jun 5, 2026
## Summary

During assistant-message streaming, blank markdown lines in the
transient active tail were prefixed with two spaces. Ratatui measured
those whitespace-only lines as two viewport rows, so list- and
table-heavy answers showed doubled vertical gaps while streaming and
then visibly compacted when finalized into scrollback.

- keep whitespace-only `StreamingAgentTailCell` lines structurally empty
while preserving nonblank message prefixes
- clear impossible hyperlink metadata when normalizing a blank tail line
- add an inline snapshot and height regression proving one blank
markdown line occupies one viewport row

Related to #26618, but fixes a separate live-tail row-height issue
rather than stale committed markdown content.

## How to Test

Recommended before/after reproduction:

1. Start the latest Codex build without this change.
2. Submit this exact prompt:

> Send 20 different lists: bullets vs numbered, simple vs complex with
paragraphs in between items, etc. Intertwine them with some tables and
some paragraphs.

3. While the answer streams, observe duplicated vertical gaps around
list items and paragraphs. When the answer finishes, observe the spacing
compact.
4. Start this branch with `just c` and submit the same prompt.
5. Confirm each intended blank markdown line occupies one terminal row
throughout streaming and that the spacing does not compact or jump when
the answer finishes.
6. As a focused regression, verify the sections after the first table,
especially loose lists with paragraphs between items; those blank rows
should remain stable throughout streaming.

Targeted tests:

- `just test -p codex-tui
streaming_agent_tail_blank_line_uses_one_viewport_row`
- `just test -p codex-tui history_cell::tests`

## Test Notes

- Verified the exact prompt above in a real tmux TUI using latest Codex
and this branch as the before/after comparison.
- The full `just test -p codex-tui` run completed 2,782 of 2,784 tests
successfully. Two unrelated guardian feature-flag tests fail
reproducibly in isolation because the expected `OverrideTurnContext`
message is absent.
- `just argument-comment-lint` is blocked locally by the existing Bazel
`compiler-rt` missing-header glob error; the touched Rust diff was
inspected manually for opaque positional literals.
@etraut-openai

Copy link
Copy Markdown
Collaborator

@codex review

@etraut-openai etraut-openai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I did a local review, and codex found several issues that look like real bugs.

Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 31bd9c3fe9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs
@fcoury-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 072b439810

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs
@fcoury-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 896c79ee12

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs
@fcoury-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5c720ae96d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs
@fcoury-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5c720ae96d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/chatwidget/turn_runtime.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
@fcoury-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bc4d51d03b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs
@fcoury-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5f38c6cda1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/chatwidget/turn_runtime.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/chatwidget/tests/status_and_layout.rs
Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
@fcoury-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 664fdd2d6e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
@fcoury-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1fc298a5c7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
@fcoury-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cf8935be51

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/chatwidget/turn_runtime.rs
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
@fcoury-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 032c5dfe54

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs Outdated
Comment thread codex-rs/tui/src/streaming/controller.rs
@fcoury-oai

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6e7fc95d59

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/tui/src/streaming/controller.rs
dkropachev pushed a commit to dkropachev/codex that referenced this pull request Jun 9, 2026
## Summary

During assistant-message streaming, blank markdown lines in the
transient active tail were prefixed with two spaces. Ratatui measured
those whitespace-only lines as two viewport rows, so list- and
table-heavy answers showed doubled vertical gaps while streaming and
then visibly compacted when finalized into scrollback.

- keep whitespace-only `StreamingAgentTailCell` lines structurally empty
while preserving nonblank message prefixes
- clear impossible hyperlink metadata when normalizing a blank tail line
- add an inline snapshot and height regression proving one blank
markdown line occupies one viewport row

Related to openai#26618, but fixes a separate live-tail row-height issue
rather than stale committed markdown content.

## How to Test

Recommended before/after reproduction:

1. Start the latest Codex build without this change.
2. Submit this exact prompt:

> Send 20 different lists: bullets vs numbered, simple vs complex with
paragraphs in between items, etc. Intertwine them with some tables and
some paragraphs.

3. While the answer streams, observe duplicated vertical gaps around
list items and paragraphs. When the answer finishes, observe the spacing
compact.
4. Start this branch with `just c` and submit the same prompt.
5. Confirm each intended blank markdown line occupies one terminal row
throughout streaming and that the spacing does not compact or jump when
the answer finishes.
6. As a focused regression, verify the sections after the first table,
especially loose lists with paragraphs between items; those blank rows
should remain stable throughout streaming.

Targeted tests:

- `just test -p codex-tui
streaming_agent_tail_blank_line_uses_one_viewport_row`
- `just test -p codex-tui history_cell::tests`

## Test Notes

- Verified the exact prompt above in a real tmux TUI using latest Codex
and this branch as the before/after comparison.
- The full `just test -p codex-tui` run completed 2,782 of 2,784 tests
successfully. Two unrelated guardian feature-flag tests fail
reproducibly in isolation because the expected `OverrideTurnContext`
message is absent.
- `just argument-comment-lint` is blocked locally by the existing Bazel
`compiler-rt` missing-header glob error; the touched Rust diff was
inspected manually for opaque positional literals.
dkropachev pushed a commit to dkropachev/codex that referenced this pull request Jun 9, 2026
## Summary

During assistant-message streaming, blank markdown lines in the
transient active tail were prefixed with two spaces. Ratatui measured
those whitespace-only lines as two viewport rows, so list- and
table-heavy answers showed doubled vertical gaps while streaming and
then visibly compacted when finalized into scrollback.

- keep whitespace-only `StreamingAgentTailCell` lines structurally empty
while preserving nonblank message prefixes
- clear impossible hyperlink metadata when normalizing a blank tail line
- add an inline snapshot and height regression proving one blank
markdown line occupies one viewport row

Related to openai#26618, but fixes a separate live-tail row-height issue
rather than stale committed markdown content.

## How to Test

Recommended before/after reproduction:

1. Start the latest Codex build without this change.
2. Submit this exact prompt:

> Send 20 different lists: bullets vs numbered, simple vs complex with
paragraphs in between items, etc. Intertwine them with some tables and
some paragraphs.

3. While the answer streams, observe duplicated vertical gaps around
list items and paragraphs. When the answer finishes, observe the spacing
compact.
4. Start this branch with `just c` and submit the same prompt.
5. Confirm each intended blank markdown line occupies one terminal row
throughout streaming and that the spacing does not compact or jump when
the answer finishes.
6. As a focused regression, verify the sections after the first table,
especially loose lists with paragraphs between items; those blank rows
should remain stable throughout streaming.

Targeted tests:

- `just test -p codex-tui
streaming_agent_tail_blank_line_uses_one_viewport_row`
- `just test -p codex-tui history_cell::tests`

## Test Notes

- Verified the exact prompt above in a real tmux TUI using latest Codex
and this branch as the before/after comparison.
- The full `just test -p codex-tui` run completed 2,782 of 2,784 tests
successfully. Two unrelated guardian feature-flag tests fail
reproducibly in isolation because the expected `OverrideTurnContext`
message is absent.
- `just argument-comment-lint` is blocked locally by the existing Bazel
`compiler-rt` missing-header glob error; the touched Rust diff was
inspected manually for opaque positional literals.
dkropachev pushed a commit to dkropachev/codex that referenced this pull request Jun 9, 2026
## Summary

During assistant-message streaming, blank markdown lines in the
transient active tail were prefixed with two spaces. Ratatui measured
those whitespace-only lines as two viewport rows, so list- and
table-heavy answers showed doubled vertical gaps while streaming and
then visibly compacted when finalized into scrollback.

- keep whitespace-only `StreamingAgentTailCell` lines structurally empty
while preserving nonblank message prefixes
- clear impossible hyperlink metadata when normalizing a blank tail line
- add an inline snapshot and height regression proving one blank
markdown line occupies one viewport row

Related to openai#26618, but fixes a separate live-tail row-height issue
rather than stale committed markdown content.

## How to Test

Recommended before/after reproduction:

1. Start the latest Codex build without this change.
2. Submit this exact prompt:

> Send 20 different lists: bullets vs numbered, simple vs complex with
paragraphs in between items, etc. Intertwine them with some tables and
some paragraphs.

3. While the answer streams, observe duplicated vertical gaps around
list items and paragraphs. When the answer finishes, observe the spacing
compact.
4. Start this branch with `just c` and submit the same prompt.
5. Confirm each intended blank markdown line occupies one terminal row
throughout streaming and that the spacing does not compact or jump when
the answer finishes.
6. As a focused regression, verify the sections after the first table,
especially loose lists with paragraphs between items; those blank rows
should remain stable throughout streaming.

Targeted tests:

- `just test -p codex-tui
streaming_agent_tail_blank_line_uses_one_viewport_row`
- `just test -p codex-tui history_cell::tests`

## Test Notes

- Verified the exact prompt above in a real tmux TUI using latest Codex
and this branch as the before/after comparison.
- The full `just test -p codex-tui` run completed 2,782 of 2,784 tests
successfully. Two unrelated guardian feature-flag tests fail
reproducibly in isolation because the expected `OverrideTurnContext`
message is absent.
- `just argument-comment-lint` is blocked locally by the existing Bazel
`compiler-rt` missing-header glob error; the touched Rust diff was
inspected manually for opaque positional literals.
dkropachev pushed a commit to dkropachev/codex that referenced this pull request Jun 9, 2026
## Summary

During assistant-message streaming, blank markdown lines in the
transient active tail were prefixed with two spaces. Ratatui measured
those whitespace-only lines as two viewport rows, so list- and
table-heavy answers showed doubled vertical gaps while streaming and
then visibly compacted when finalized into scrollback.

- keep whitespace-only `StreamingAgentTailCell` lines structurally empty
while preserving nonblank message prefixes
- clear impossible hyperlink metadata when normalizing a blank tail line
- add an inline snapshot and height regression proving one blank
markdown line occupies one viewport row

Related to openai#26618, but fixes a separate live-tail row-height issue
rather than stale committed markdown content.

## How to Test

Recommended before/after reproduction:

1. Start the latest Codex build without this change.
2. Submit this exact prompt:

> Send 20 different lists: bullets vs numbered, simple vs complex with
paragraphs in between items, etc. Intertwine them with some tables and
some paragraphs.

3. While the answer streams, observe duplicated vertical gaps around
list items and paragraphs. When the answer finishes, observe the spacing
compact.
4. Start this branch with `just c` and submit the same prompt.
5. Confirm each intended blank markdown line occupies one terminal row
throughout streaming and that the spacing does not compact or jump when
the answer finishes.
6. As a focused regression, verify the sections after the first table,
especially loose lists with paragraphs between items; those blank rows
should remain stable throughout streaming.

Targeted tests:

- `just test -p codex-tui
streaming_agent_tail_blank_line_uses_one_viewport_row`
- `just test -p codex-tui history_cell::tests`

## Test Notes

- Verified the exact prompt above in a real tmux TUI using latest Codex
and this branch as the before/after comparison.
- The full `just test -p codex-tui` run completed 2,782 of 2,784 tests
successfully. Two unrelated guardian feature-flag tests fail
reproducibly in isolation because the expected `OverrideTurnContext`
message is absent.
- `just argument-comment-lint` is blocked locally by the existing Bazel
`compiler-rt` missing-header glob error; the touched Rust diff was
inspected manually for opaque positional literals.
dkropachev pushed a commit to dkropachev/codex that referenced this pull request Jun 9, 2026
## Summary

During assistant-message streaming, blank markdown lines in the
transient active tail were prefixed with two spaces. Ratatui measured
those whitespace-only lines as two viewport rows, so list- and
table-heavy answers showed doubled vertical gaps while streaming and
then visibly compacted when finalized into scrollback.

- keep whitespace-only `StreamingAgentTailCell` lines structurally empty
while preserving nonblank message prefixes
- clear impossible hyperlink metadata when normalizing a blank tail line
- add an inline snapshot and height regression proving one blank
markdown line occupies one viewport row

Related to openai#26618, but fixes a separate live-tail row-height issue
rather than stale committed markdown content.

## How to Test

Recommended before/after reproduction:

1. Start the latest Codex build without this change.
2. Submit this exact prompt:

> Send 20 different lists: bullets vs numbered, simple vs complex with
paragraphs in between items, etc. Intertwine them with some tables and
some paragraphs.

3. While the answer streams, observe duplicated vertical gaps around
list items and paragraphs. When the answer finishes, observe the spacing
compact.
4. Start this branch with `just c` and submit the same prompt.
5. Confirm each intended blank markdown line occupies one terminal row
throughout streaming and that the spacing does not compact or jump when
the answer finishes.
6. As a focused regression, verify the sections after the first table,
especially loose lists with paragraphs between items; those blank rows
should remain stable throughout streaming.

Targeted tests:

- `just test -p codex-tui
streaming_agent_tail_blank_line_uses_one_viewport_row`
- `just test -p codex-tui history_cell::tests`

## Test Notes

- Verified the exact prompt above in a real tmux TUI using latest Codex
and this branch as the before/after comparison.
- The full `just test -p codex-tui` run completed 2,782 of 2,784 tests
successfully. Two unrelated guardian feature-flag tests fail
reproducibly in isolation because the expected `OverrideTurnContext`
message is absent.
- `just argument-comment-lint` is blocked locally by the existing Bazel
`compiler-rt` missing-header glob error; the touched Rust diff was
inspected manually for opaque positional literals.
dkropachev pushed a commit to dkropachev/codex that referenced this pull request Jun 9, 2026
## Summary

During assistant-message streaming, blank markdown lines in the
transient active tail were prefixed with two spaces. Ratatui measured
those whitespace-only lines as two viewport rows, so list- and
table-heavy answers showed doubled vertical gaps while streaming and
then visibly compacted when finalized into scrollback.

- keep whitespace-only `StreamingAgentTailCell` lines structurally empty
while preserving nonblank message prefixes
- clear impossible hyperlink metadata when normalizing a blank tail line
- add an inline snapshot and height regression proving one blank
markdown line occupies one viewport row

Related to openai#26618, but fixes a separate live-tail row-height issue
rather than stale committed markdown content.

## How to Test

Recommended before/after reproduction:

1. Start the latest Codex build without this change.
2. Submit this exact prompt:

> Send 20 different lists: bullets vs numbered, simple vs complex with
paragraphs in between items, etc. Intertwine them with some tables and
some paragraphs.

3. While the answer streams, observe duplicated vertical gaps around
list items and paragraphs. When the answer finishes, observe the spacing
compact.
4. Start this branch with `just c` and submit the same prompt.
5. Confirm each intended blank markdown line occupies one terminal row
throughout streaming and that the spacing does not compact or jump when
the answer finishes.
6. As a focused regression, verify the sections after the first table,
especially loose lists with paragraphs between items; those blank rows
should remain stable throughout streaming.

Targeted tests:

- `just test -p codex-tui
streaming_agent_tail_blank_line_uses_one_viewport_row`
- `just test -p codex-tui history_cell::tests`

## Test Notes

- Verified the exact prompt above in a real tmux TUI using latest Codex
and this branch as the before/after comparison.
- The full `just test -p codex-tui` run completed 2,782 of 2,784 tests
successfully. Two unrelated guardian feature-flag tests fail
reproducibly in isolation because the expected `OverrideTurnContext`
message is absent.
- `just argument-comment-lint` is blocked locally by the existing Bazel
`compiler-rt` missing-header glob error; the touched Rust diff was
inspected manually for opaque positional literals.
dkropachev pushed a commit to dkropachev/codex that referenced this pull request Jun 9, 2026
## Summary

During assistant-message streaming, blank markdown lines in the
transient active tail were prefixed with two spaces. Ratatui measured
those whitespace-only lines as two viewport rows, so list- and
table-heavy answers showed doubled vertical gaps while streaming and
then visibly compacted when finalized into scrollback.

- keep whitespace-only `StreamingAgentTailCell` lines structurally empty
while preserving nonblank message prefixes
- clear impossible hyperlink metadata when normalizing a blank tail line
- add an inline snapshot and height regression proving one blank
markdown line occupies one viewport row

Related to openai#26618, but fixes a separate live-tail row-height issue
rather than stale committed markdown content.

## How to Test

Recommended before/after reproduction:

1. Start the latest Codex build without this change.
2. Submit this exact prompt:

> Send 20 different lists: bullets vs numbered, simple vs complex with
paragraphs in between items, etc. Intertwine them with some tables and
some paragraphs.

3. While the answer streams, observe duplicated vertical gaps around
list items and paragraphs. When the answer finishes, observe the spacing
compact.
4. Start this branch with `just c` and submit the same prompt.
5. Confirm each intended blank markdown line occupies one terminal row
throughout streaming and that the spacing does not compact or jump when
the answer finishes.
6. As a focused regression, verify the sections after the first table,
especially loose lists with paragraphs between items; those blank rows
should remain stable throughout streaming.

Targeted tests:

- `just test -p codex-tui
streaming_agent_tail_blank_line_uses_one_viewport_row`
- `just test -p codex-tui history_cell::tests`

## Test Notes

- Verified the exact prompt above in a real tmux TUI using latest Codex
and this branch as the before/after comparison.
- The full `just test -p codex-tui` run completed 2,782 of 2,784 tests
successfully. Two unrelated guardian feature-flag tests fail
reproducibly in isolation because the expected `OverrideTurnContext`
message is absent.
- `just argument-comment-lint` is blocked locally by the existing Bazel
`compiler-rt` missing-header glob error; the touched Rust diff was
inspected manually for opaque positional literals.
dkropachev pushed a commit to dkropachev/codex that referenced this pull request Jun 9, 2026
## Summary

During assistant-message streaming, blank markdown lines in the
transient active tail were prefixed with two spaces. Ratatui measured
those whitespace-only lines as two viewport rows, so list- and
table-heavy answers showed doubled vertical gaps while streaming and
then visibly compacted when finalized into scrollback.

- keep whitespace-only `StreamingAgentTailCell` lines structurally empty
while preserving nonblank message prefixes
- clear impossible hyperlink metadata when normalizing a blank tail line
- add an inline snapshot and height regression proving one blank
markdown line occupies one viewport row

Related to openai#26618, but fixes a separate live-tail row-height issue
rather than stale committed markdown content.

## How to Test

Recommended before/after reproduction:

1. Start the latest Codex build without this change.
2. Submit this exact prompt:

> Send 20 different lists: bullets vs numbered, simple vs complex with
paragraphs in between items, etc. Intertwine them with some tables and
some paragraphs.

3. While the answer streams, observe duplicated vertical gaps around
list items and paragraphs. When the answer finishes, observe the spacing
compact.
4. Start this branch with `just c` and submit the same prompt.
5. Confirm each intended blank markdown line occupies one terminal row
throughout streaming and that the spacing does not compact or jump when
the answer finishes.
6. As a focused regression, verify the sections after the first table,
especially loose lists with paragraphs between items; those blank rows
should remain stable throughout streaming.

Targeted tests:

- `just test -p codex-tui
streaming_agent_tail_blank_line_uses_one_viewport_row`
- `just test -p codex-tui history_cell::tests`

## Test Notes

- Verified the exact prompt above in a real tmux TUI using latest Codex
and this branch as the before/after comparison.
- The full `just test -p codex-tui` run completed 2,782 of 2,784 tests
successfully. Two unrelated guardian feature-flag tests fail
reproducibly in isolation because the expected `OverrideTurnContext`
message is absent.
- `just argument-comment-lint` is blocked locally by the existing Bazel
`compiler-rt` missing-header glob error; the touched Rust diff was
inspected manually for opaque positional literals.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants