Pablan, as it stands
Self-hosted knowledge management for SMEs: a split-screen Markdown editor whose sections an LLM refines while you write, and RAG question answering over the documents that result. FastAPI + Postgres/pgvector on the back, SvelteKit on the front, everything OpenAI-compatible and self-hostable. Squashed into a single commit; the development history stays local. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CA43ZJda8Rbp2hKXNy8f6b
This commit is contained in:
co-authored by
Claude Opus 5
parent
68d3a43191
commit
784b76baf7
@@ -0,0 +1,43 @@
|
||||
"""Rows to API shapes.
|
||||
|
||||
A conversation has no title column: the first message is the title, derived
|
||||
here so the list and the detail can never disagree about what a conversation
|
||||
is called.
|
||||
"""
|
||||
|
||||
from app.api.conversations.schemas import MessageOut, MessageSource
|
||||
from app.models import Message
|
||||
from app.modes.query import excerpt as clean_excerpt
|
||||
|
||||
TITLE_LENGTH = 80
|
||||
|
||||
|
||||
def title(first_message: str | None) -> str | None:
|
||||
if not first_message:
|
||||
return None
|
||||
flattened = " ".join(first_message.split())
|
||||
if len(flattened) <= TITLE_LENGTH:
|
||||
return flattened
|
||||
return flattened[: TITLE_LENGTH - 1] + "…"
|
||||
|
||||
|
||||
def message_out(message: Message) -> MessageOut:
|
||||
"""Message + its citation snapshot from `meta` (assistant turns only).
|
||||
|
||||
The excerpt is re-cleaned on the way out, not just on the way in. It is
|
||||
a presentation detail frozen at answer time, so an improvement to the
|
||||
cleaning would otherwise only reach conversations created afterwards,
|
||||
and every existing citation would keep showing raw Markdown forever.
|
||||
Cleaning is idempotent, so text stored by a newer backend passes
|
||||
through untouched.
|
||||
"""
|
||||
meta = message.meta or {}
|
||||
sources = [
|
||||
MessageSource.model_validate(item).model_copy(
|
||||
update={"excerpt": clean_excerpt(item.get("excerpt", ""))}
|
||||
)
|
||||
for item in meta.get("sources", [])
|
||||
]
|
||||
return MessageOut.model_validate(message).model_copy(
|
||||
update={"sources": sources, "fallback": meta.get("fallback")}
|
||||
)
|
||||
Reference in New Issue
Block a user