Prompt suggestions on the new-chat screen
A blank composer is the least helpful thing a chat client can show someone who has just installed one. Three cards now sit under the empty state, and an administrator manages them at /admin/suggestions. Clicking a card fills the composer and stops there. It deliberately does not send: every default ends mid-sentence, because a card is a starting point rather than a question somebody already asked, and the caret lands where the person has to start typing. Seeding is guarded by a settings flag, not by "is the table empty" -- otherwise an administrator who decided against them would get all three back on every restart. Capped at twelve, six shown: past a dozen this is a menu, and a menu on the empty screen is a worse blank page than a blank page. The cards are gated on there being no chat at all, not on the thread being empty. An empty chat someone opened on purpose already has a model and a prompt chosen. Also fixes a pre-existing bug the position test caught. Both this and _refresh_models wrote `coalesce(max(position), -1) or -1`, and position 0 is falsy -- so the second row landed back on 0 on top of the first. The coalesce was already doing that job; the `or` was undoing it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,7 @@ from lembas.db.models.library import (
|
||||
chat_knowledge_bases,
|
||||
)
|
||||
from lembas.db.models.setting import Setting
|
||||
from lembas.db.models.suggestion import Suggestion
|
||||
from lembas.db.models.user import (
|
||||
ROLE_ADMIN,
|
||||
ROLE_PENDING,
|
||||
@@ -85,6 +86,7 @@ __all__ = [
|
||||
"Share",
|
||||
"Skill",
|
||||
"SkillRevision",
|
||||
"Suggestion",
|
||||
"User",
|
||||
"chat_knowledge_bases",
|
||||
"model_groups",
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
"""Starting points offered on the new-chat screen."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from sqlalchemy import Boolean, Integer, String, Text
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from lembas.db.base import Base, Timestamps, UUIDPrimaryKey
|
||||
|
||||
|
||||
class Suggestion(UUIDPrimaryKey, Timestamps, Base):
|
||||
"""One card on the empty chat screen.
|
||||
|
||||
Instance-wide rather than per-user: these are what an administrator wants
|
||||
people to start with, the same way the instance system prompt is. There is
|
||||
no owner_id and therefore nothing for `sharing` to decide.
|
||||
"""
|
||||
|
||||
__tablename__ = "suggestions"
|
||||
|
||||
name: Mapped[str] = mapped_column(String(120), nullable=False)
|
||||
description: Mapped[str] = mapped_column(String(300), default="")
|
||||
# What lands in the composer. Deliberately not sent on its own: it usually
|
||||
# ends mid-sentence, because a card is a starting point rather than a
|
||||
# question somebody already asked.
|
||||
prompt: Mapped[str] = mapped_column(Text, default="")
|
||||
|
||||
enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False)
|
||||
position: Mapped[int] = mapped_column(Integer, default=0, nullable=False)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<Suggestion {self.name}>"
|
||||
Reference in New Issue
Block a user