Skip to content

Commit 8887b38

Browse files
committed
fix(viz): gate ambient wash off during replay (isRunning stays true in cached playback)
1 parent 97b86c4 commit 8887b38

3 files changed

Lines changed: 16 additions & 4 deletions

File tree

src/dashboard/src/components/viz/CohortSwarmGrid.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ function CohortColumn(props: CohortColumnProps) {
172172
onOpenChat,
173173
} = props;
174174

175+
// Replay (`?replay=<id>`) is cached playback; the reducer keeps
176+
// `isRunning` true while replayed events stream, so treat replay as
177+
// non-live and suppress the ambient wash on cached cohort playback.
178+
const isReplaying = typeof window !== 'undefined'
179+
&& new URLSearchParams(window.location.search).has('replay');
175180
const ref = useRef<HTMLDivElement | null>(null);
176181
// Track whether the column has been visible at least once. Once true
177182
// we keep the LivingSwarmGrid mounted forever (canvas animation
@@ -253,7 +258,7 @@ function CohortColumn(props: CohortColumnProps) {
253258
{hasBeenVisible ? (
254259
<LivingSwarmGrid
255260
snapshot={snap}
256-
isLiveRun={state.isRunning}
261+
isLiveRun={state.isRunning && !isReplaying}
257262
previousSnapshot={prevSnap}
258263
snapshotHistory={snaps}
259264
actorName={fallbackName}

src/dashboard/src/components/viz/SwarmViz.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@ export function SwarmViz({ state, onNavigateToChat }: SwarmVizProps) {
129129
const [currentTurn, setCurrentTurn] = useState(0);
130130
const [playing, setPlaying] = useState(false);
131131
const [speed, setSpeed] = useState(1);
132+
// Replay (`?replay=<id>`) is cached playback (no new LLM cost). The run
133+
// reducer still flips `isRunning` true while replayed status events
134+
// stream, so gate on replay too: treat cached playback as non-live so
135+
// the VIZ suppresses the ambient wash just like completed/loaded runs.
136+
const isReplaying = typeof window !== 'undefined'
137+
&& new URLSearchParams(window.location.search).has('replay');
138+
const isLiveRun = state.isRunning && !isReplaying;
132139

133140
// Grid mode (new living-colony grid). Shared across both leaders so
134141
// tabs toggle in lockstep. Persisted to localStorage so the user's
@@ -1313,7 +1320,7 @@ export function SwarmViz({ state, onNavigateToChat }: SwarmVizProps) {
13131320
>
13141321
<LivingSwarmGrid
13151322
snapshot={snapA}
1316-
isLiveRun={state.isRunning}
1323+
isLiveRun={isLiveRun}
13171324
previousSnapshot={prevSnapA}
13181325
snapshotHistory={snapsA}
13191326
actorName={leaderA?.name ?? 'Leader A'}
@@ -1356,7 +1363,7 @@ export function SwarmViz({ state, onNavigateToChat }: SwarmVizProps) {
13561363
>
13571364
<LivingSwarmGrid
13581365
snapshot={snapB}
1359-
isLiveRun={state.isRunning}
1366+
isLiveRun={isLiveRun}
13601367
previousSnapshot={prevSnapB}
13611368
snapshotHistory={snapsB}
13621369
actorName={leaderB?.name ?? 'Leader B'}

src/dashboard/src/components/viz/grid/LivingSwarmGrid.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,7 @@ export function LivingSwarmGrid(props: LivingSwarmGridProps) {
899899
ref={canvasWrapRef}
900900
className={styles.canvasWrap}
901901
style={{
902-
'--tint-color': tintColor,
902+
'--tint-color': isLiveRun ? tintColor : 'transparent',
903903
'--wrap-border': wrapBorder,
904904
'--wrap-glow': wrapGlow,
905905
} as CSSProperties}

0 commit comments

Comments
 (0)