fix: mark message as interrupted locally to prevent loading re-enable
When the user clicks stop, the $effect managing $loading relies on
isConversationGenerationActive(messages) to detect streaming state.
But after invalidateAll() fetches server data, the server may not
have written interrupted:true yet (race with the stop POST). The
$effect sees streaming=true and only the stopRequested flag prevents
$loading from going back to true — but the background poller is
never removed (it only stops when streaming=false).
Fix: in stopGeneration(), immediately set lastAssistant.interrupted
= true on the local messages state. This makes the $effect see
streaming=false instantly, which:
- Sets $loading = false via the normal path (not just stopRequested)
- Removes the background poller (removeBackgroundGeneration)
- Prevents any further periodic invalidations from re-enabling loading