Skip to content

fix(tui): show in-flight coalesced tool calls in transcript overlay#8246

Merged
joshka-oai merged 2 commits intoopenai:mainfrom
Chriss4123:fix/transcript-overlay-live-tail-v2
Jan 13, 2026
Merged

fix(tui): show in-flight coalesced tool calls in transcript overlay#8246
joshka-oai merged 2 commits intoopenai:mainfrom
Chriss4123:fix/transcript-overlay-live-tail-v2

Conversation

@Chriss4123
Copy link
Contributor

Fixes #7998.

The TUI coalesces read/search/list exec calls into an in-flight "Exploring/Explored" group (ChatWidget.active_cell). The main viewport renders that active cell immediately, but the Ctrl+T transcript overlay was built only from committed transcript cells, so while the agent is still exploring the overlay can look like the tool calls are missing until a later flush boundary.

This PR makes the transcript overlay include a render-only "live tail" for the current active history cell. It doesn’t change when exec groups flush or how coalescing works; it just makes the overlay reflect what the UI already knows.

To keep overlay interactions cheap, the tail is cached and only recomputed when the active cell changes or the terminal width changes.

Testing:

  • cargo test -p codex-tui
  • cargo test -p codex-tui2

@Chriss4123 Chriss4123 force-pushed the fix/transcript-overlay-live-tail-v2 branch 4 times, most recently from a136713 to 8e87bd8 Compare December 18, 2025 22:02
@Chriss4123 Chriss4123 force-pushed the fix/transcript-overlay-live-tail-v2 branch from d51bbb3 to 1fcf9b3 Compare January 7, 2026 19:57
@joshka-oai joshka-oai self-assigned this Jan 8, 2026
Copy link
Collaborator

@joshka-oai joshka-oai left a comment

Choose a reason for hiding this comment

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

Thanks - the idea looks good and it definitely solves the problem.

My comments generally are around adding extra context around the changes to the code. This helps people (and agents) unfamiliar with the specific code paths be able to validate the code actually aligns with what it's intended to do.

I'd merge this with that extra info. Happy to update this for you, or let you go at it if you'd prefer. Mostly codex does a really good job here at adding this info with extra prompts to add the right level of docs (whereeve context / rationale / edge cases / complexity / large abstraction level gaps is needed). Mostly doc comments, some inline.

@joshka-oai
Copy link
Collaborator

@codex review this to ensure that the tui/tui2 behavior and code is the same (modulo any changes that tui2 would prevent this).

Copy link
Contributor

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

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: 1fcf9b344a

ℹ️ 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".

@etraut-openai etraut-openai added the needs-response Additional information is requested label Jan 8, 2026
@Chriss4123 Chriss4123 force-pushed the fix/transcript-overlay-live-tail-v2 branch 2 times, most recently from e029100 to fa79cfd Compare January 9, 2026 03:15
@Chriss4123
Copy link
Contributor Author

Thanks - the idea looks good and it definitely solves the problem.

My comments generally are around adding extra context around the changes to the code. This helps people (and agents) unfamiliar with the specific code paths be able to validate the code actually aligns with what it's intended to do.

I'd merge this with that extra info. Happy to update this for you, or let you go at it if you'd prefer. Mostly codex does a really good job here at adding this info with extra prompts to add the right level of docs (whereeve context / rationale / edge cases / complexity / large abstraction level gaps is needed). Mostly doc comments, some inline.

Applied all of your suggestions. Please take another look when you get the time.

@Chriss4123
Copy link
Contributor Author

@codex review

Copy link
Contributor

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

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: fa79cfdc3b

ℹ️ 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".

When the TUI coalesces read/search/list exec calls into the in-flight “Exploring/Explored” group, the main viewport renders that active history cell immediately, but the Ctrl+T transcript overlay only shows committed transcript cells. Mid-turn, that can make the transcript look like those tool calls haven’t happened yet until a later flush boundary.

Render the current active history cell as a read-only “live tail” at the bottom of the transcript overlay, without changing any coalescing/flush behavior. Cache the tail and only recompute when the active cell changes or the terminal width changes so scrolling/highlighting in the overlay stays cheap.

Also request a redraw when an exec call completes but the coalesced exec cell remains active, to avoid the transcript “catching up” on an unrelated later event.

Includes tui2 parity.
@Chriss4123 Chriss4123 force-pushed the fix/transcript-overlay-live-tail-v2 branch from fa79cfd to f145310 Compare January 9, 2026 03:43
@Chriss4123
Copy link
Contributor Author

@codex review

@chatgpt-codex-connector
Copy link
Contributor

Codex Review: Didn't find any major issues. Chef's kiss.

ℹ️ 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".

@Chriss4123
Copy link
Contributor Author

@joshka-oai I think it's ready for a re-review.

@Chriss4123
Copy link
Contributor Author

The failing test looks like a flaky timeout. Other platforms passed and this PR only touches tui/tui2.

Can someone rerun the Windows ARM job?

@etraut-openai etraut-openai removed the needs-response Additional information is requested label Jan 9, 2026
Document how Ctrl+T transcript overlay stays in sync with the
in-flight active cell via a cached live tail keyed by width,
revision, stream continuation, and animation tick.

Move subsystem rationale into Rustdoc and align module, type, and
function docs between tui and tui2 without changing behavior.
@joshka-oai
Copy link
Collaborator

I added a bunch of docs in ba041f8 to help understand how this works a bit better.

Codex prompt for the docs update: (generated by GPT 5.2 and then tweaked a bit after looking at the output).

Prompt

You are in **DOCUMENTATION PASS** mode.

This is a *non-functional* pass over an existing change.
Your job is to make the system understandable to humans without altering what it does.

---

## **Hard rules**

You MUST:

* Not change runtime behavior
* Not refactor logic
* Not rename public APIs unless required for clarity (if so, propose instead of doing)
* Not delete code

You MAY:

* Add or edit documentation comments
* Add module headers
* Improve commit messages
* Improve PR description text
* Add or adjust tests only if they clarify intent (prefer none)

If you believe a code change is needed for clarity, **call it out but do not implement it.**

---

## **Documentation style rules (Rust-aware)**

When writing Rust documentation:

* The first paragraph of every doc comment must be a single-sentence summary.
* Follow with normal narrative paragraphs, not labeled sections.
* Do NOT invent headings like “Overview”, “Postcondition”, or “Misuse”.
* Integrate guarantees, assumptions, and pitfalls into prose.
* Use `# Errors`, `# Panics`, or `# Safety` only when they are genuinely required by Rustdoc conventions.
* Misuse examples should appear as natural warnings in text, not as standalone sections.

Inline comments inside functions must follow this rule:

* Comments that explain **design, ownership, layering, invariants, or architecture** belong in **doc comments**.
* Inline comments should only explain **local logic** (why this branch, why this calculation).
* If a comment would still be true if the function body were rewritten, it must be a doc comment.

For module-level docs:

* Describe **invariants and mechanisms**, not “things going wrong”.
* Prefer “The overlay is kept in sync by…” over “If the overlay looks stale…”.

---

## **Your goals**

Convert implicit intent into explicit narrative.

A reviewer should be able to answer:

* *What problem does this solve?*
* *How does this subsystem work?*
* *What are the contracts and invariants?*
* *What could break and how would I debug it?*

---

## **Step 1 — PR-level narrative**

Write (or rewrite) a PR description that includes:

**Problem**

* What user or system pain this change addresses

**Mental model**

* How this part of the system works after the change

**Non-goals**

* What was intentionally NOT done

**Tradeoffs**

* What was sacrificed or risked

**Architecture**

* How this interacts with existing subsystems

**Observability**

* How to tell this is working or broken

**Tests**

* What was added/changed and why it is sufficient

Avoid line-by-line diff walkthroughs.

---

## **Step 2 — Intent vs implementation**

Infer the intended design from the code.

Then list:

* Where the implementation clearly matches that intent
* Where it is ambiguous, leaky, or inconsistent
* What minimal documentation would remove that ambiguity

Be blunt.

---

## **Step 3 — Module-level documentation**

For every non-trivial module, write or update a header doc comment that explains:

* What problem this module solves
* The key concepts and terms used here
* Responsibilities vs non-responsibilities
* How it fits into the larger system
* Any state machine or lifecycle it manages
* Where invariants are enforced and by which components

Use narrative prose, not API listings.

---

## **Step 4 — Type-level documentation**

For every public struct, enum, trait, or type, document:

* Its role in the system
* What it represents conceptually
* The invariants it maintains
* Who is allowed to construct or mutate it
* Threading or ownership assumptions

Do NOT restate field names — explain meaning and contracts.

---

## **Step 5 — Function-level documentation**

For every public function or method, document:

* Why it exists
* When it should be used
* Preconditions and assumptions
* Postconditions and guarantees
* What errors mean and how callers should respond
* One realistic misuse case and what bug it would cause

Do not translate the signature into English.

---

## **Step 6 — Implicit contracts**

List the real contracts this change introduces:

* Which are enforced by types
* Which are enforced by tests
* Which are only assumptions in developers’ heads

Recommend where each should be documented.

---

## **Step 7 — Debuggability**

Describe:

* Which components are responsible for keeping key invariants true
* Where state is synchronized or cached
* What logs, flags, or entry points matter when tracing behavior

This should read as architecture, not as a list of bugs.

---

## **Step 8 — Commit story**

Rewrite or propose commit messages so that each commit answers:

* What changed in system behavior
* Why it changed
* What it enables or blocks next

Avoid “refactor”, “cleanup”, or “minor”.

---

## **Final output**

Produce:

1. Updated PR description
2. Documentation patches (module, type, function)
3. A short list of **design inconsistencies or risks** you discovered

If something doesn’t make sense, say so.

You are not here to be polite — you are here to make the system legible.

And output:

Updated PR description

Problem

Ctrl+T transcript overlay can omit in-flight coalesced tool calls because it
renders only committed transcript cells while the main viewport can render the
current in-flight ChatWidget.active_cell immediately.

Mental model

The UI has both committed transcript cells (finalized HistoryCell entries) and
an in-flight active cell that can mutate in place while streaming, often
representing a coalesced exec/tool group. The transcript overlay renders
committed cells plus a render-only live tail derived from the current active
cell. The live tail is cached and only recomputed when its cache key changes,
which is derived from terminal width (wrapping), active-cell revision
(in-place mutations), stream continuation (spacing), and animation tick
(time-based visuals).

Non-goals

This does not change coalescing rules, flush boundaries, or when active cells
become committed. It does not change tool-call semantics or transcript
persistence; it is a rendering-only improvement for the overlay.

Tradeoffs

This adds cache invalidation complexity: correctness depends on bumping an
active-cell revision (and/or providing an animation tick) when the active cell
mutates in place. The mechanism is implemented in both codex-tui and codex-tui2,
which keeps behavior consistent but risks drift if future changes are not
applied in lockstep.

Architecture

App special-cases transcript overlay draws to sync a live tail from ChatWidget
into TranscriptOverlay. TranscriptOverlay remains the owner of committed
transcript cells; the live tail is an optional appended renderable.
HistoryCell::transcript_animation_tick() allows time-dependent transcript output
(spinner/shimmer) to invalidate the cached tail without requiring data mutation.

Observability

Manual verification is to open Ctrl+T while an exploring/coalesced active cell
is still in-flight and confirm the overlay includes the same in-flight tool-call
group the main viewport shows. The overlay is kept in sync by App passing an
active-cell key and transcript lines into TranscriptOverlay::sync_live_tail; the
key must change when the active cell mutates or animates.

Tests

Snapshot tests validate that the transcript overlay renders a live tail appended
after committed cells and that identical keys short-circuit recomputation. Unit
tests validate that active-cell revision bumps occur on specific in-place
mutations (e.g. unified exec wait cell command display becoming known late) so
cached tails are invalidated.

Documentation patches (module, type, function)

Module-level docs (invariants + mechanisms)

  • codex-rs/tui/src/app_backtrack.rs:1
  • codex-rs/tui/src/chatwidget.rs:1
  • codex-rs/tui/src/pager_overlay.rs:1
  • codex-rs/tui/src/history_cell.rs:1
  • codex-rs/tui2/src/app_backtrack.rs:1
  • codex-rs/tui2/src/chatwidget.rs:1
  • codex-rs/tui2/src/pager_overlay.rs:1
  • codex-rs/tui2/src/history_cell.rs:1

Type-level docs (cache key + invariants)

  • codex-rs/tui/src/chatwidget.rs (ChatWidget.active_cell_revision, ActiveCellTranscriptKey)
  • codex-rs/tui/src/pager_overlay.rs (TranscriptOverlay live tail storage model)
  • codex-rs/tui/src/history_cell.rs (HistoryCell::transcript_animation_tick, UnifiedExecWaitCell::update_command_display)
  • Mirrored in codex-rs/tui2/src/chatwidget.rs, codex-rs/tui2/src/pager_overlay.rs, codex-rs/tui2/src/history_cell.rs

Function-level docs (why/when/guarantees/pitfalls)

  • codex-rs/tui/src/app_backtrack.rs (overlay_forward_event)
  • codex-rs/tui/src/chatwidget.rs (active_cell_transcript_key, active_cell_transcript_lines)
  • codex-rs/tui/src/pager_overlay.rs (sync_live_tail, take_live_tail_renderable)
  • codex-rs/tui/src/history_cell.rs (transcript_animation_tick, UnifiedExecWaitCell::update_command_display)
  • Mirrored in codex-rs/tui2 equivalents where present

Validation performed

  • cd codex-rs && just fmt
  • cd codex-rs && cargo test -p codex-tui
  • cd codex-rs && cargo test -p codex-tui2

Design inconsistencies / risks

  • Cache invalidation is a distributed responsibility: any future in-place active
    cell transcript mutation that forgets to bump active_cell_revision (or expose
    an animation tick) can leave the transcript overlay live tail out of sync with
    the main viewport.
  • TranscriptOverlay tail handling assumes a structural invariant that the live
    tail, when present, is exactly one trailing renderable after the committed cell
    renderables; if renderable construction changes in a way that violates that
    assumption, tail insertion/removal logic becomes incorrect.
  • codex-tui and codex-tui2 duplicate the live-tail mechanism; the documentation
    is aligned, but the implementation can still drift unless changes continue to
    be applied in lockstep.

@joshka-oai joshka-oai enabled auto-merge (squash) January 13, 2026 02:52
@joshka-oai joshka-oai merged commit 12779c7 into openai:main Jan 13, 2026
45 of 53 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Jan 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Transcript view omits in-progress “Explored” tool calls until a later flush

3 participants