At 100% zoom in windows 541-760px tall the Room page was 60px taller than
the window and the Send to room button started cut off (S10's 160px log
minimum). A short-window Room grid moves the members line beside the
section title and puts the composer on one row; under 650px the header
compacts. Keyed on the CSS viewport only, so 2x displays get the same
layout; page-flow layouts are unchanged.
An upward reader scroll that left the newest message's end at the
viewport bottom still read as at tail, so new content pulled the reader
down past the composer pin. The message-end tail position now counts
only on a downward scroll. A channel-disabled Conversation pins the
newest message instead of a composer that cannot send. S11 and S12
visibility checks require the whole newest message whenever it fits
above the composer.
In page flow (200% zoom, short or narrow windows) the transcript now
follows with the composer's bottom at the viewport bottom and the newest
message above it. Absent or disabled composers keep the S11 pin. Narrow
Room composers stack in one column. S11's visibility check accepts the
newest message's end when it is taller than half the viewport.
In page flow (200% zoom), the S11 follow logic re-pinned the document on
any scroll without wheel, touch, pointer or scroll-key input, so Tab,
Shift+Tab, focus(), find-style reveals and dialog return focus were pulled
back to the tail with focus thousands of pixels off screen.
Re-pin only a downward scroll with no reader input while following (scroll
anchoring as content grows). Count Tab as reader input, expire the reader
flag after two frames, and resume following when a transcript is opened.
S10 review P1: the max-height:700px page-flow rule moved the composer
off screen on 1440x700 and 1366x650 windows at 100%. Page flow now
applies only at max-height:540px (200% tab zoom on desktop screens) or
below 320px wide. S10 review P2: the moved Room details control keeps
its 44px target.
At 200% zoom on a 390px viewport the compact conversation row held a decision status on one line, so Needs your input pushed the page 12px sideways. The status now takes its own line under the icon and text and wraps. The Overview column margin and split were scoped to Overview, so Requirements keeps its base geometry. Tests cover a real decision status and the Requirements position.
The conversation and room logs pinned to the bottom only on mutation, so a
log that settled shorter after paint stopped 23px short on every load.
Re-pin on resize too, and cover the room log.
A harness or catalogue save clears routesView. A route draft made while
the save was in flight kept routesSection from adopting the fresh read,
so the next render dereferenced a null view and Routing disappeared
until a page reload. Adopt the fresh view whenever none is held; the
draft keeps its cells.
S6a review P2 1.
Register the documented 65536-token default output limit and retain the existing 128000-token context window for glm-5.3-flash. Other model registrations are unchanged.
Pi's isRecoverableLength (pi-ai dist/utils/overflow.js:163), used by agent-session.js:1659, now treats a length stop below 65536 output tokens as recoverable, including context-clamped requests or a lower provider cap. Pi then compacts and retries. It allows one recovery in a row: the flag resets on a new user message or a successful assistant message that is not a length stop, so tool rounds can re-arm it within one prompt.
The recovery happens inside one runner attempt. The turn marker reflects the final agent_end, and the failed and retried messages still count in that message's usage delta, so three runner attempts need not mean three provider calls.
The 128000 context and 16384 reserve are unchanged, so threshold compaction still starts above 111616 tokens. Output clamping now starts above about 58368 estimated input tokens instead of 107520. No new local refusal.
This commit can be dropped without affecting Part A.
Review round fixes for the length continuation in Part A.
Before each continuation the runner now reads processing.status as well as
state. A halted, invalid or unreadable processing state starts no further
attempt; the message is left unread with no reply and no failure record, as
for a halt during any turn.
A failed state or processing read keeps the empty length classification, so
the sender gets no RESULT. The chief notice and the trail event name how many
attempts hit the limit.
usage.end for the message id now runs in a finally block, so it closes once
even when an attempt throws.
The library citation retry no longer starts continuations. They would run
outside the message's usage bracket, and the retry's own bracket is refused
(#1853). An empty length retry fails visibly instead, with no fixed RESULT.
Tests cover a halt between attempts, a failed continuation check on the plain
and library paths, a throwing attempt, a library continuation that succeeds,
and the retry path.
Pi could spend its output limit on thinking and the runner relayed an empty answer as a result. Preserve final stop metadata and allow two bounded continuations, accounting for the whole message in one transcript usage delta.
Record exhaustion on the message trail and notify the chief without an automatic reply cycle. Mount the shared notice prefix in the sandbox.
Merges ui-dev-projects (c907e4d0d) onto the Settings slice (65df511f3).
Conflicts resolved by keeping both sides: the slice 3 token block in
tokens.css, and in bus.js the Settings display redirect plus the
Projects route test. Whole webui suite on Node 26: 729 passed, 0 failed.
Review round 1 on 4048e0f60 found two defects.
Startup recovery ran unconditionally. A continuation retry now refuses
while processing is halted, so a broker restart with a waiting
continuation failed with processing-halted. Startup recovery now waits
while processing is halted or invalid, as the periodic pass does;
processing.resume schedules it again.
#continuationStarting matched any launch without an end, so an older
launch whose end was lost (#1851) hid every later run's end. Only the
target's latest lifecycle event counts now.
Both regression tests fail on 4048e0f60 and pass here.
Expose the parent message class on agent delivery so the runner can stop automatic replies to answers while preserving requests and ordinary relays. Scope continuation retry versions to the target, suppress notices during processing halts and unclaimed launches, and clarify the instance-running refusal.
The bus suite excludes project-files.test.mjs because its 1 MiB socket test timed out on both the candidate and the untouched 1186cf7b1 base.
The chat.js fetch wrapper recorded a request-not-found from /api/requests/<id>/workspace as a missing request and then served a synthetic 404 to the request panel's rereads, failing 11 request-browser tests. Only the request's own read records a miss now. Adds a regression test that fails on 9d3eb9e11, and bounds the r3 held-404 test's check on its refresh reads, which raced Files' cached repaint under load.