"""Full-page routes: the chat shell and the user's own settings.""" from __future__ import annotations from fastapi import APIRouter, HTTPException, Request, status from fastapi.responses import RedirectResponse from sqlalchemy import select from sqlalchemy.orm import Session as DBSession from lembas.api.deps import Db, RequiredUser from lembas.db.models import Chat, Folder, Message, User from lembas.security import permissions from lembas.services import chat as chat_service from lembas.services.markdown import render_markdown from lembas.web.templating import render router = APIRouter(tags=["pages"]) def _chat_context(db: DBSession, user: User, chat: Chat | None) -> dict: """Model lists and permissions every chat page needs. Pinned and unpinned are split here rather than in the template so the picker's optgroups stay a plain loop. """ models = chat_service.available_models(db, user) current = next((m for m in models if m.model_id == chat.model_id), None) if chat else None pinned = [m for m in models if m.pinned] return { "models": models, "pinned_models": pinned, # Excludes the pinned ones: they already have their own optgroup, and # listing a model twice gives the