Add settings page, model management, and chat UX improvements
- Settings infrastructure: key-value settings table, GET/PUT API, Pinia store - Configurable assistant name (default "Fable") in settings and LLM system prompt - Model catalog with 18 models in 3 categories (General Purpose, Coding, Uncensored / Creative Writing) with download/select/remove functionality - Move Ollama status indicator from chat views to global nav bar - Chat bubble layout: user messages right-aligned, assistant left-aligned - Floating dark input bar with auto-focus and circular send button - Fix HTML entity rendering (' apostrophe issue in marked/DOMPurify pipeline) - Fix new chat button navigation (fetchConversation before router.push) - Recent chats section on home page with "New Chat" button - Update summary.md with Phase 4.5 changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import httpx
|
||||
|
||||
from fabledassistant.config import Config
|
||||
from fabledassistant.services.notes import get_note, list_notes
|
||||
from fabledassistant.services.settings import get_setting
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -139,8 +140,9 @@ async def build_context(
|
||||
user_message: str,
|
||||
) -> list[dict]:
|
||||
"""Build messages array for Ollama with system prompt and context."""
|
||||
assistant_name = await get_setting("assistant_name", "Fable")
|
||||
system_parts = [
|
||||
"You are a helpful assistant integrated into a note-taking and task-tracking app called Fabled Assistant. "
|
||||
f"You are a helpful assistant named {assistant_name}, integrated into a note-taking and task-tracking app called Fabled Assistant. "
|
||||
"Help users with their notes, tasks, and general questions. "
|
||||
"When note context is provided, use it to give relevant answers."
|
||||
]
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
from sqlalchemy import select
|
||||
|
||||
from fabledassistant.models import async_session
|
||||
from fabledassistant.models.setting import Setting
|
||||
|
||||
|
||||
async def get_setting(key: str, default: str = "") -> str:
|
||||
async with async_session() as session:
|
||||
result = await session.execute(select(Setting).where(Setting.key == key))
|
||||
setting = result.scalar_one_or_none()
|
||||
return setting.value if setting else default
|
||||
|
||||
|
||||
async def set_setting(key: str, value: str) -> None:
|
||||
async with async_session() as session:
|
||||
result = await session.execute(select(Setting).where(Setting.key == key))
|
||||
setting = result.scalar_one_or_none()
|
||||
if setting:
|
||||
setting.value = value
|
||||
else:
|
||||
session.add(Setting(key=key, value=value))
|
||||
await session.commit()
|
||||
|
||||
|
||||
async def get_all_settings() -> dict[str, str]:
|
||||
async with async_session() as session:
|
||||
result = await session.execute(select(Setting))
|
||||
return {s.key: s.value for s in result.scalars().all()}
|
||||
Reference in New Issue
Block a user