Files
windmill/frontend
Guilhem LemouelandClaude Opus 5 dda7ab2f30 refactor(chat): give a flow chat turn a module of its own
A turn was not a thing. What one is made of lived in three places — a
reactive status record, a non-reactive runtime map, and locals inside the
function following the job — so the question every piece of a turn's work
has to answer, "am I still the turn this chat is on?", had no owner. Each
await site answered it again from whatever abort flag it had in scope, and
each new await needed another answer; the counter this replaces was the
eighth such answer in as many review rounds.

`Turn` holds the run, the handle that stops it, the cursor its stream
resumes from, the rows it is writing and the timers it armed, and the chat
keys one per conversation. Work carries its turn and passes `isCurrent`
before writing, so a frame buffered before a Stop, a poll dispatched a tick
ago, or a settle that outlived its own turn all land nowhere instead of in
whatever replaced it. Ending a turn is one call rather than an abort, two
timers and a pair of reveals that every caller had to remember, and the
sites that release one say which turn they mean.

The chat itself is keyed on its flow and workspace, so changing flow builds
a new panel rather than re-pointing the old one. That is what makes the
guards removable: nothing survives a flow change to need them.

Fixes found while doing this, each of which the old shape allowed: a
two-minute polling deadline that outlived its turn and stopped the next
one's reading; a run launched into a stopped turn that nothing could name;
a conversation-list refresh on every poll tick of a new chat's first turn;
a failed page walk that freed a chat whose run it never got to ask about;
and a Stop during a launch that tore down the turn that came after it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 03:59:48 +02:00
..

Windmill frontend

The Windmill frontend written in Svelte 5 + Tailwind CSS

The frontend is under AGPL, see the LICENSE file at the root of this repo