From 1cedd4692fefa2abbc1b2934c93d6cd10f3d4ebc Mon Sep 17 00:00:00 2001 From: Tristan Simas Date: Thu, 8 Oct 2026 18:09:25 -0400 Subject: [PATCH] Keep body publication completion off input pumps --- src/toad/widgets/prepared_markdown.py | 8 ++++---- src/toad/widgets/transcript_history.py | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/toad/widgets/prepared_markdown.py b/src/toad/widgets/prepared_markdown.py index edee6580c..974f4c284 100644 --- a/src/toad/widgets/prepared_markdown.py +++ b/src/toad/widgets/prepared_markdown.py @@ -239,10 +239,10 @@ def reconstructible_children(self) -> tuple[Widget, ...]: def _initialize_document(self, markdown: str | None) -> AwaitComplete: # Mount admits the body; its materialization worker owns prepared - # content. Observe the original initialization on this body's pump, - # after mount, rather than holding the conversation's mount receipt. - # The native implementation retains source consumption and TOC order. - self.call_later(super()._initialize_document(markdown)) + # content. Observe that original receipt after completion; waiting on + # this pump would hold wheel delivery behind background preparation. + # Native source consumption and TOC completion remain unchanged. + super()._initialize_document(markdown).call_when_ready(self) return AwaitComplete.nothing() def retire_body_resources(self) -> None: diff --git a/src/toad/widgets/transcript_history.py b/src/toad/widgets/transcript_history.py index 64b443f8a..9d32c9424 100644 --- a/src/toad/widgets/transcript_history.py +++ b/src/toad/widgets/transcript_history.py @@ -169,7 +169,7 @@ def set_categories(self, selected: frozenset[type[MessageCategory]]) -> None: self.selected_categories = selected apply_block_filter(self, selected) if self.is_attached and not visible and self.message_category in selected and not self.children: - self.publish_body(self.materialize_native_body).call_next(self) + self.publish_body(self.materialize_native_body).call_when_ready(self) def compose(self) -> ComposeResult: # A filtered source slot retains identity/coverage, not hidden native @@ -409,14 +409,14 @@ def _follow_source_tail(self) -> bool: async def _report_coverage(self, page: TranscriptPage, fragments: tuple[TranscriptFragment, ...]) -> None: if self._source_state.reports_coverage: from toad.widgets.conversation import Conversation - # Transfer covered native display inside the page admission. Join - # stream teardown on the original Conversation pump after these - # source/tree locks release, never while mount waits for coverage. + # Transfer covered native display inside the page admission. The + # original retirement receipt owns teardown; observe its completed + # result without holding the Conversation pump or mount admission. # Standalone saved viewers have no live transcript to transfer. # Resolve custody from native ancestry, not a second owner field. for ancestor in self.ancestors: if isinstance(ancestor, Conversation): - ancestor.transcript.covered(TranscriptCoverage(page.events), self).call_next(ancestor) + ancestor.transcript.covered(TranscriptCoverage(page.events), self).call_when_ready(ancestor) break def publish_committed(self) -> None: