Two kinds of work, and a switch to say which
The sidebar rendered an agent chat and an ordinary one identically, in one list, so hours of machine work sat among a morning's questions. A switch below the pinned models now shows one kind at a time, stored on the account so it follows the reader to another browser. Three things it does that are not the obvious version: The switch is inside the fragment it swaps. Targeting only the tree would leave the two buttons showing the side you had just left -- the request works and the interface says otherwise, which is the failure this codebase keeps cataloguing. A folder can be emptied by the filter, or have been empty all along, and only the first is a reason to hide it. `shown_in` is that line: a folder somebody made a moment ago and has not filled yet stays on both sides, or it can never be found again, let alone filed into. With agent chats switched off there is no switch, and the sidebar goes back to showing everything rather than to one side of a fork nobody can move. An administrator turning the feature off would otherwise strand whoever last left the switch on Agents in an empty sidebar with no way out. The control reuses the composer's `.segmented`, which is the same choice in a different place, and the verb goes on the input rather than the wrapper. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -76,6 +76,41 @@ async def set_layout(db: Db, user: RequiredUser, widths: dict = Body(...)) -> di
|
||||
return {"ok": True, "layout": kept}
|
||||
|
||||
|
||||
@router.post("/sidebar-kind")
|
||||
async def set_sidebar_kind(
|
||||
request: Request, db: Db, user: RequiredUser, kind: str = Form("")
|
||||
) -> Response:
|
||||
"""Switch the sidebar between ordinary chats and agent chats.
|
||||
|
||||
Saves and re-renders in one round trip, because the two cannot be allowed to
|
||||
disagree: a switch that stored a choice and left the tree showing the other
|
||||
side would look broken, and re-rendering without storing would lose it on the
|
||||
next navigation. The tree comes back as a fragment rather than an `HX-Refresh`
|
||||
-- a full reload is what `api/folders.py` does for a structural change, and it
|
||||
would throw away the folder open/closed state on every flick of the switch,
|
||||
which is the same thing `/api/chats/unread` avoids by swapping out of band.
|
||||
|
||||
An unrecognised value is refused rather than stored: `sidebar_kind` reads it
|
||||
back as "chat" anyway, so storing it would be a preference that silently
|
||||
does nothing.
|
||||
"""
|
||||
from lembas.api.pages import sidebar_context
|
||||
from lembas.db.models import KINDS
|
||||
from lembas.web.templating import templates
|
||||
|
||||
if kind not in KINDS:
|
||||
return Response(status_code=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
user.settings_json = {**(user.settings_json or {}), "sidebar_kind": kind}
|
||||
db.commit()
|
||||
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"partials/_sidebar_tree.html",
|
||||
{"chat": None, "user": user, **sidebar_context(db, user)},
|
||||
)
|
||||
|
||||
|
||||
@router.post("/default-model")
|
||||
async def set_default_model(
|
||||
db: Db, user: RequiredUser, model_id: str = Form("")
|
||||
|
||||
Reference in New Issue
Block a user