Skip to content

Commit 8871dfb

Browse files
tonyfettesclaude
andcommitted
Carry the rehydrated preview as an option through Sync
sync_effect turned a missing preview into an empty string, which LivePreview::sync then read as the instruction to clear the host. The effect carries String? and the DOM side branches on None. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dp6jf4fKxaVzVq2heQR6dX
1 parent ad4ec86 commit 8871dfb

3 files changed

Lines changed: 16 additions & 18 deletions

File tree

desktop/frontend/transcript/component/live_reasoning.mbt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ priv enum LiveReasoningMsg {
8888
#warnings("-unused_value")
8989
priv enum LiveReasoningEffect {
9090
NoChange
91-
Sync(target~ : String, step_label~ : String?, content~ : String)
91+
// `content` is the stored preview to rehydrate; `None` means the target
92+
// has no open preview and the host is cleared.
93+
Sync(target~ : String, step_label~ : String?, content~ : String?)
9294
Append(target~ : String, content~ : String)
9395
Hide(target~ : String)
9496
Reset
@@ -133,10 +135,7 @@ fn LiveReasoningState::sync_effect(
133135
Sync(
134136
target=target.key.wire(),
135137
step_label=target.step_label,
136-
content=self
137-
.preview_for(target.key)
138-
.map(preview => preview.content())
139-
.unwrap_or(""),
138+
content=self.preview_for(target.key).map(preview => preview.content()),
140139
)
141140
}
142141
}

desktop/frontend/transcript/component/live_reasoning_dom.mbt

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ fn LivePreview::sync(
218218
self : LivePreview,
219219
target : String,
220220
step_label : String?,
221-
content : String,
221+
content : String?,
222222
) -> Unit {
223223
if self.target == Some(target) &&
224224
self.step_label == step_label &&
@@ -231,16 +231,11 @@ fn LivePreview::sync(
231231
self.cancel_pending()
232232
self.target = Some(target)
233233
self.step_label = step_label
234-
let host = live_host()
235-
if content.is_empty() {
236-
self.clear_host(host)
237-
} else {
238-
match host {
239-
Some(host) => {
240-
let _ = self.build_card(host, content)
241-
}
242-
None => self.clear_host(None)
234+
match (content, live_host()) {
235+
(Some(content), Some(host)) => {
236+
let _ = self.build_card(host, content)
243237
}
238+
(_, host) => self.clear_host(host)
244239
}
245240
}
246241

desktop/frontend/transcript/component/live_reasoning_wbtest.mbt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ test "live reasoning appends by owner and semantic finish deletes it" {
4747
let (focused, focus_effect) = empty.update(Focused(target))
4848
assert_eq(
4949
focus_effect,
50-
Sync(target=key.wire(), step_label=Some("#1"), content=""),
50+
Sync(target=key.wire(), step_label=Some("#1"), content=None),
5151
)
5252
let (first, first_effect) = focused.update(Delta(key, "think"))
5353
assert_eq(first_effect, Append(target=key.wire(), content="think"))
@@ -57,7 +57,7 @@ test "live reasoning appends by owner and semantic finish deletes it" {
5757
let (_, hydrate_effect) = live.update(Focused(target))
5858
assert_eq(
5959
hydrate_effect,
60-
Sync(target=key.wire(), step_label=Some("#1"), content="thinking"),
60+
Sync(target=key.wire(), step_label=Some("#1"), content=Some("thinking")),
6161
)
6262

6363
// The full reasoning event is a semantic boundary, not a durable commit.
@@ -140,7 +140,11 @@ test "live reasoning keeps concurrent conversations and runs isolated" {
140140
)
141141
assert_eq(
142142
focus_effect,
143-
Sync(target=local_r8.wire(), step_label=Some("#1"), content="local-current"),
143+
Sync(
144+
target=local_r8.wire(),
145+
step_label=Some("#1"),
146+
content=Some("local-current"),
147+
),
144148
)
145149
let (with_background, background_effect) = focused.update(
146150
Delta(remote_r7, "-more"),

0 commit comments

Comments
 (0)