fix(chat): take the fork exception from the thread's tail, not its last reply
The exception that keeps a live-named reply forkable — the backend's tail fork lands exactly there — was keyed on "newest assistant run", which is one message short of the tail when the user steers at the very end of a turn: that promotes as assistant + user message, so the reply is still the newest one and the tail fork would land after the steered message. `computeTurnMetadataPatches` withholds `source_turn_id` from a parse ending on a user turn, so nothing would have corrected it later either. Render items now carry `isThreadTail` — nothing follows, counting a user message or a compaction divider and stepping over blocks that render nothing — and the fork gate reads that instead.
X
xintaofei committed
e7d10e137cdf8c048b0ac7ed9639c83cd61bc327
Parent: a0d54b0