Six things that looked like they worked

None of these fails loudly and two of them correct themselves if you reload,
which is why five were found by reading rather than by anybody reporting them.

The reply that lost its author is the one worth knowing about: the frame that
replaces a bubble when a reply lands was looking the models up as nobody, and
"no user" answers "no models" rather than "all models" -- so every finished
reply swapped the model's avatar for the plain mark and put the instance's name
where the model's should be, until the next page load put it back.

Beside it: a concurrency quota enforced on two of the six paths that start a
reply, including neither of the two most used; a custom theme whose success and
warning colours moved the text and left the background behind; a phone shell
sized to one viewport inside a document sized to another, which is the reported
scroll past the bottom of Settings; a whole conversation's Markdown rendered on
every page load and read by nothing; a skip guard inert since it was written;
and an endpoint nothing has ever called.

The scroll fix folded five near-identical scroller rules into one, which is
also where the containment they were all missing now lives.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 12:49:26 +00:00
co-authored by Claude Opus 5
parent d73a791c86
commit 92070d7879
14 changed files with 259 additions and 82 deletions
-8
View File
@@ -21,7 +21,6 @@ from lembas.api.pages import _chat_context, sidebar_context
from lembas.db.models import Message, Schedule
from lembas.services import messages as messages_service
from lembas.services import schedules as schedules_service
from lembas.services.markdown import render_markdown
from lembas.services.schedule import clock
from lembas.services.schedule import rule as rule_service
from lembas.web.templating import render
@@ -31,11 +30,6 @@ log = logging.getLogger(__name__)
router = APIRouter(tags=["messages"])
def _bodies(messages: list[Message]) -> dict[str, str]:
"""Markdown rendered server-side, keyed by id, as `chat_detail` does."""
return {m.id: render_markdown(m.content) for m in messages if m.role == "user"}
@router.get("/messages")
async def messages_page(request: Request, db: Db, user: RequiredUser):
conversation = messages_service.for_user(db, user)
@@ -61,7 +55,6 @@ async def messages_page(request: Request, db: Db, user: RequiredUser):
"chat": conversation,
"messages": live,
"compacted": [],
"bodies": _bodies(live),
"inherited_prompt": "",
"inherited_from": "",
"more_before": bool(live) and messages_service.has_more_before(
@@ -109,7 +102,6 @@ async def messages_history(
"messages/_history.html",
{
"messages": page,
"bodies": _bodies(page),
"more_before": messages_service.has_more_before(db, conversation, page[0]),
"oldest_id": page[0].id,
# `render()` injects `user` and friends; `TemplateResponse` does