- Writing assistant: inject project notes as context (definition-tagged first), wikilink suggestions - Link suggestions: server-side endpoint finds unlinked term occurrences, NoteEditorView sidebar panel - Project-scoped RAG: ChatView ProjectSelector filters semantic+keyword search to selected project - Semantic search tool: LLM search_notes upgraded to hybrid semantic (0.40 threshold) + keyword merge - SSE race condition fix: drain remaining events after stream loop exits in chat.py and notes.py - RAG_AUTO_SNIPPET raised 800→4000; sidebar include uses full note body; MAX_BODY_CHARS 8000→24000 - Enter-to-submit on writing assistant instruction textareas (note and task editors) - DiffView: equal-line collapsing with 3-line context around changes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
54 lines
1.8 KiB
Python
54 lines
1.8 KiB
Python
from sqlalchemy import select, text
|
|
|
|
from fabledassistant.models import async_session
|
|
from fabledassistant.models.note_version import NoteVersion
|
|
|
|
MAX_VERSIONS = 20
|
|
|
|
|
|
async def create_version(
|
|
user_id: int, note_id: int, body: str, title: str, tags: list[str] | None = None
|
|
) -> NoteVersion:
|
|
async with async_session() as session:
|
|
version = NoteVersion(note_id=note_id, user_id=user_id, body=body, title=title, tags=tags or [])
|
|
session.add(version)
|
|
await session.commit()
|
|
await session.refresh(version)
|
|
|
|
# Prune versions beyond MAX_VERSIONS
|
|
await session.execute(
|
|
text("""
|
|
DELETE FROM note_versions
|
|
WHERE id IN (
|
|
SELECT id FROM note_versions
|
|
WHERE note_id = :note_id AND user_id = :user_id
|
|
ORDER BY created_at DESC
|
|
OFFSET :max_versions
|
|
)
|
|
""").bindparams(note_id=note_id, user_id=user_id, max_versions=MAX_VERSIONS)
|
|
)
|
|
await session.commit()
|
|
return version
|
|
|
|
|
|
async def list_versions(user_id: int, note_id: int) -> list[NoteVersion]:
|
|
async with async_session() as session:
|
|
result = await session.execute(
|
|
select(NoteVersion)
|
|
.where(NoteVersion.note_id == note_id, NoteVersion.user_id == user_id)
|
|
.order_by(NoteVersion.created_at.desc())
|
|
)
|
|
return list(result.scalars().all())
|
|
|
|
|
|
async def get_version(user_id: int, note_id: int, version_id: int) -> NoteVersion | None:
|
|
async with async_session() as session:
|
|
result = await session.execute(
|
|
select(NoteVersion).where(
|
|
NoteVersion.id == version_id,
|
|
NoteVersion.note_id == note_id,
|
|
NoteVersion.user_id == user_id,
|
|
)
|
|
)
|
|
return result.scalars().first()
|